CI #5
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - '**' | |
| pull_request: | |
| branches: | |
| - '**' | |
| permissions: | |
| contents: write # Needed to commit coverage badge on main branch | |
| pull-requests: write | |
| jobs: | |
| test: | |
| name: Test and Coverage | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.21' | |
| cache: true | |
| - name: Install bc for floating-point math | |
| run: sudo apt-get update && sudo apt-get install -y bc | |
| - name: Run tests with coverage | |
| run: | | |
| go test -v -race -coverprofile=coverage.out -covermode=atomic ./... | |
| go tool cover -html=coverage.out -o coverage.html | |
| - name: Calculate coverage | |
| id: coverage | |
| run: | | |
| # Calculate total coverage | |
| COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//') | |
| echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT | |
| echo "Total coverage: $COVERAGE%" | |
| # Calculate coverage by package | |
| echo "## Coverage by Package" > coverage_report.txt | |
| echo "" >> coverage_report.txt | |
| go tool cover -func=coverage.out | grep -v "total:" | awk '{print $1, $3}' | sort -t: -k1,1 -u | while read line; do | |
| echo "- $line" >> coverage_report.txt | |
| done | |
| # Get coverage summary | |
| echo "" >> coverage_report.txt | |
| echo "## Summary" >> coverage_report.txt | |
| echo "" >> coverage_report.txt | |
| go tool cover -func=coverage.out | tail -1 >> coverage_report.txt | |
| - name: Check coverage threshold | |
| run: | | |
| COVERAGE=${{ steps.coverage.outputs.coverage }} | |
| THRESHOLD=80.0 | |
| echo "Coverage: $COVERAGE%" | |
| echo "Threshold: $THRESHOLD%" | |
| # Use bc for floating point comparison | |
| if [ $(echo "$COVERAGE < $THRESHOLD" | bc -l) -eq 1 ]; then | |
| echo "❌ Coverage $COVERAGE% is below threshold $THRESHOLD%" | |
| exit 1 | |
| else | |
| echo "✅ Coverage $COVERAGE% meets threshold $THRESHOLD%" | |
| fi | |
| - name: Generate coverage badge data | |
| if: github.event_name == 'pull_request' | |
| id: badge | |
| run: | | |
| COVERAGE=${{ steps.coverage.outputs.coverage }} | |
| # Determine badge color based on coverage | |
| if [ $(echo "$COVERAGE >= 90" | bc -l) -eq 1 ]; then | |
| COLOR="brightgreen" | |
| elif [ $(echo "$COVERAGE >= 80" | bc -l) -eq 1 ]; then | |
| COLOR="green" | |
| elif [ $(echo "$COVERAGE >= 70" | bc -l) -eq 1 ]; then | |
| COLOR="yellow" | |
| elif [ $(echo "$COVERAGE >= 60" | bc -l) -eq 1 ]; then | |
| COLOR="orange" | |
| else | |
| COLOR="red" | |
| fi | |
| echo "color=$COLOR" >> $GITHUB_OUTPUT | |
| - name: Generate PR comment body | |
| if: github.event_name == 'pull_request' | |
| id: comment | |
| env: | |
| COVERAGE: ${{ steps.coverage.outputs.coverage }} | |
| BADGE_COLOR: ${{ steps.badge.outputs.color }} | |
| COMMIT_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| # Determine status | |
| if [ $(echo "$COVERAGE >= 80" | bc -l) -eq 1 ]; then | |
| STATUS="✅ PASSED - Coverage meets minimum threshold" | |
| STATUS_EMOJI="✅" | |
| else | |
| STATUS="❌ FAILED - Coverage below minimum threshold" | |
| STATUS_EMOJI="❌" | |
| fi | |
| # Create comment body using heredoc | |
| cat > comment_final.txt << EOF | |
| ## 📊 Test Coverage Report | |
| **Overall Coverage:** ${COVERAGE}%  | |
| **Threshold:** 80% ${STATUS_EMOJI} | |
| <details> | |
| <summary>Coverage by Package</summary> | |
| \`\`\` | |
| $(cat coverage_report.txt) | |
| \`\`\` | |
| </details> | |
| --- | |
| 📈 **Coverage Status:** ${STATUS} | |
| <sub>Updated for commit ${COMMIT_SHA}</sub> | |
| EOF | |
| - name: Comment on PR | |
| if: github.event_name == 'pull_request' | |
| uses: marocchino/sticky-pull-request-comment@v2 | |
| with: | |
| header: coverage | |
| path: comment_final.txt | |
| - name: Generate coverage badge for main branch | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| env: | |
| COVERAGE: ${{ steps.coverage.outputs.coverage }} | |
| run: | | |
| # Determine badge color | |
| if [ $(echo "$COVERAGE >= 90" | bc -l) -eq 1 ]; then | |
| COLOR="brightgreen" | |
| elif [ $(echo "$COVERAGE >= 80" | bc -l) -eq 1 ]; then | |
| COLOR="green" | |
| elif [ $(echo "$COVERAGE >= 70" | bc -l) -eq 1 ]; then | |
| COLOR="yellow" | |
| elif [ $(echo "$COVERAGE >= 60" | bc -l) -eq 1 ]; then | |
| COLOR="orange" | |
| else | |
| COLOR="red" | |
| fi | |
| # Create badge JSON for shields.io endpoint schema | |
| mkdir -p .github/badges | |
| cat > .github/badges/coverage.json << EOF | |
| { | |
| "schemaVersion": 1, | |
| "label": "coverage", | |
| "message": "${COVERAGE}%", | |
| "color": "${COLOR}" | |
| } | |
| EOF | |
| echo "Generated coverage badge: ${COVERAGE}% (${COLOR})" | |
| - name: Commit coverage badge to main | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| run: | | |
| git config --local user.email "github-actions[bot]@users.noreply.github.com" | |
| git config --local user.name "github-actions[bot]" | |
| git add .github/badges/coverage.json | |
| git diff --staged --quiet || git commit -m "chore: update coverage badge [skip ci]" | |
| git push | |
| - name: Upload coverage artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: | | |
| coverage.out | |
| coverage.html | |
| coverage_report.txt | |
| retention-days: 30 | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.21' | |
| cache: true | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@v4 | |
| with: | |
| version: latest | |
| args: --timeout=5m | |
| build: | |
| name: Build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.21' | |
| cache: true | |
| - name: Build | |
| run: go build -v ./... | |
| - name: Build CLI binary | |
| run: go build -o pup . | |
| - name: Verify binary | |
| run: ./pup --version |