diff --git a/.github/workflows/test-action.yml b/.github/workflows/test-action.yml new file mode 100644 index 0000000..fbe1149 --- /dev/null +++ b/.github/workflows/test-action.yml @@ -0,0 +1,43 @@ +name: Test go-covercheck action + +on: + workflow_dispatch: + pull_request: + paths: + - 'action.yml' + +jobs: + test-action: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.24' + + - name: Run tests to generate coverage + run: go test -v -coverprofile=coverage.out ./... + + - name: Test go-covercheck action - basic usage + uses: ./ + with: + coverage-file: coverage.out + + - name: Test go-covercheck action - with custom thresholds + uses: ./ + with: + coverage-file: coverage.out + statement-threshold: "75" + block-threshold: "60" + format: json + + - name: Test go-covercheck action - with skip patterns + uses: ./ + with: + coverage-file: coverage.out + skip: "test,mock" + no-color: "true" \ No newline at end of file diff --git a/README.md b/README.md index 6198f7a..963ed41 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,70 @@ Or you can use a tag which maps to a specific version: docker pull ghcr.io/mach6/go-covercheck:0.4.1 ``` +### 🚀 GitHub Action + +You can use the official GitHub Action to run go-covercheck in your CI/CD workflows: + +```yaml +- name: Run coverage check + uses: mach6/go-covercheck@v1 + with: + coverage-file: coverage.out +``` + +#### GitHub Action Inputs + +| Input | Description | Required | Default | +|-------|-------------|----------|---------| +| `coverage-file` | Path to the coverage profile file | No | `coverage.out` | +| `config-file` | Path to the go-covercheck config file | No | _(uses default config)_ | +| `statement-threshold` | Global statement threshold to enforce (0=disabled) | No | _(uses config default)_ | +| `block-threshold` | Global block threshold to enforce (0=disabled) | No | _(uses config default)_ | +| `total-statement-threshold` | Total statement threshold to enforce (0=disabled) | No | _(uses config default)_ | +| `total-block-threshold` | Total block threshold to enforce (0=disabled) | No | _(uses config default)_ | +| `format` | Output format (table\|json\|yaml\|md\|html\|csv\|tsv) | No | _(uses config default)_ | +| `skip` | Regex patterns of files/packages to skip (comma-separated) | No | | +| `no-color` | Disable color output (true/false) | No | `false` | +| `save-history` | Save coverage result to history (true/false) | No | `false` | +| `history-file` | Path to the history file | No | _(uses config default)_ | +| `label` | Optional label for history entry | No | | +| `version` | Version of go-covercheck to install | No | `latest` | + +#### GitHub Action Examples + +**Basic usage:** +```yaml +steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.24' + - run: go test -v -coverprofile=coverage.out ./... + - uses: mach6/go-covercheck@v1 + with: + coverage-file: coverage.out +``` + +**With custom thresholds:** +```yaml +- uses: mach6/go-covercheck@v1 + with: + coverage-file: coverage.out + statement-threshold: "80" + block-threshold: "70" + format: json +``` + +**With skip patterns and history:** +```yaml +- uses: mach6/go-covercheck@v1 + with: + coverage-file: coverage.out + skip: "mocks,testdata,cmd" + save-history: "true" + label: "v1.2.3" +``` + ## 📋 Usage ### ⚙️ Configure diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..6963c7e --- /dev/null +++ b/action.yml @@ -0,0 +1,147 @@ +name: 'go-covercheck' +description: 'Enforce test coverage thresholds in Go projects' +author: 'mach6' +branding: + icon: 'shield' + color: 'green' + +inputs: + coverage-file: + description: 'Path to the coverage profile file' + required: false + default: 'coverage.out' + config-file: + description: 'Path to the go-covercheck config file' + required: false + default: '' + statement-threshold: + description: 'Global statement threshold to enforce (0=disabled)' + required: false + default: '' + block-threshold: + description: 'Global block threshold to enforce (0=disabled)' + required: false + default: '' + total-statement-threshold: + description: 'Total statement threshold to enforce (0=disabled)' + required: false + default: '' + total-block-threshold: + description: 'Total block threshold to enforce (0=disabled)' + required: false + default: '' + format: + description: 'Output format (table|json|yaml|md|html|csv|tsv)' + required: false + default: '' + skip: + description: 'Regex patterns of files/packages to skip (comma-separated)' + required: false + default: '' + no-color: + description: 'Disable color output' + required: false + default: 'false' + save-history: + description: 'Save coverage result to history' + required: false + default: 'false' + history-file: + description: 'Path to the history file' + required: false + default: '' + label: + description: 'Optional label for history entry' + required: false + default: '' + version: + description: 'Version of go-covercheck to install' + required: false + default: 'latest' + +runs: + using: 'composite' + steps: + - name: Install go-covercheck + shell: bash + run: | + echo "Installing go-covercheck..." + if [ "${{ inputs.version }}" == "latest" ]; then + go install github.com/mach6/go-covercheck/cmd/go-covercheck@latest + else + go install github.com/mach6/go-covercheck/cmd/go-covercheck@${{ inputs.version }} + fi + + # Add Go bin directory to PATH + echo "$HOME/go/bin" >> $GITHUB_PATH + + - name: Run go-covercheck + shell: bash + run: | + # Build arguments array + args=() + + # Add coverage file (positional argument) + if [ -f "${{ inputs.coverage-file }}" ]; then + args+=("${{ inputs.coverage-file }}") + else + echo "Error: Coverage file '${{ inputs.coverage-file }}' not found" + exit 1 + fi + + # Add optional flags with values + if [ -n "${{ inputs.config-file }}" ]; then + args+=("--config=${{ inputs.config-file }}") + fi + + if [ -n "${{ inputs.statement-threshold }}" ]; then + args+=("--statement-threshold=${{ inputs.statement-threshold }}") + fi + + if [ -n "${{ inputs.block-threshold }}" ]; then + args+=("--block-threshold=${{ inputs.block-threshold }}") + fi + + if [ -n "${{ inputs.total-statement-threshold }}" ]; then + args+=("--total-statement-threshold=${{ inputs.total-statement-threshold }}") + fi + + if [ -n "${{ inputs.total-block-threshold }}" ]; then + args+=("--total-block-threshold=${{ inputs.total-block-threshold }}") + fi + + if [ -n "${{ inputs.format }}" ]; then + args+=("--format=${{ inputs.format }}") + fi + + if [ -n "${{ inputs.skip }}" ]; then + # Split comma-separated skip patterns and add each as separate --skip argument + IFS=',' read -ra SKIP_PATTERNS <<< "${{ inputs.skip }}" + for pattern in "${SKIP_PATTERNS[@]}"; do + pattern=$(echo "$pattern" | xargs) # trim whitespace + if [ -n "$pattern" ]; then + args+=("--skip=$pattern") + fi + done + fi + + # Add boolean flags + if [ "${{ inputs.no-color }}" == "true" ]; then + args+=("--no-color") + fi + + if [ "${{ inputs.save-history }}" == "true" ]; then + args+=("--save-history") + fi + + if [ -n "${{ inputs.history-file }}" ]; then + args+=("--history-file=${{ inputs.history-file }}") + fi + + if [ -n "${{ inputs.label }}" ]; then + args+=("--label=${{ inputs.label }}") + fi + + # Run go-covercheck + echo "Running go-covercheck with arguments: ${args[*]}" + go-covercheck "${args[@]}" \ No newline at end of file diff --git a/samples/github-action-workflow.yml b/samples/github-action-workflow.yml new file mode 100644 index 0000000..8cfc0a3 --- /dev/null +++ b/samples/github-action-workflow.yml @@ -0,0 +1,32 @@ +# Example GitHub Action Workflow using go-covercheck + +name: Coverage Check + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + coverage: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.24' + + - name: Run tests with coverage + run: go test -v -coverprofile=coverage.out ./... + + - name: Run coverage check + uses: mach6/go-covercheck@v1 + with: + coverage-file: coverage.out + statement-threshold: "80" + block-threshold: "70" \ No newline at end of file