Files
onvif-go/.github/workflows/ci.yml
T
0x524a d13fdb0e0a chore: update Go version in CI workflows for consistency and improved compatibility
- Changed Go version from '1.24' to '1.24.x' across all CI workflows to ensure compatibility with patch releases.
- Modified arguments for the golangci-lint action to streamline configuration.
- Updated gosec and govulncheck commands to improve error handling and reporting.
2025-12-02 23:14:10 -05:00

256 lines
8.2 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: CI
on:
push:
branches: [master, main]
pull_request:
branches: [master, main]
types: [opened, synchronize, reopened]
permissions:
contents: read
checks: write
pull-requests: write
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
GO_VERSION: '1.24.x'
jobs:
# Stage 1: Format Check (fastest - fail immediately if code isn't formatted)
fmt:
name: Format Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Check formatting
run: |
unformatted=$(gofmt -s -l . | grep -v vendor || true)
if [ -n "$unformatted" ]; then
echo "❌ The following files are not properly formatted:"
echo "$unformatted"
echo ""
echo "Run 'gofmt -s -w .' to fix formatting issues"
exit 1
fi
echo "✅ All files are properly formatted"
# Stage 2: Lint (depends on fmt)
lint:
name: Lint
runs-on: ubuntu-latest
needs: fmt
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go modules
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-${{ env.GO_VERSION }}-
- name: Download dependencies
run: go mod download
- name: Run go vet
run: go vet ./...
- name: Run golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v6.5.0
with:
version: latest
args: --timeout=5m
# Stage 3: Test with Coverage (depends on lint)
test:
name: Test & Coverage
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Full history for SonarCloud
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go modules
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-${{ env.GO_VERSION }}-
- name: Download dependencies
run: go mod download
- name: Run tests with coverage
run: |
go test -v -race -covermode=atomic -coverprofile=coverage.out -json ./... > test-report.json 2>&1 || true
# Ensure coverage file exists even if tests fail
if [ ! -f coverage.out ]; then
echo "mode: atomic" > coverage.out
fi
- name: Display coverage summary
run: |
echo "📊 Coverage Summary:"
go tool cover -func=coverage.out | tail -20
- name: Upload coverage artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: coverage-reports
path: |
coverage.out
test-report.json
retention-days: 7
- name: Upload to Codecov
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v4.6.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.out
flags: unittests
name: codecov-onvif-go
# Don't fail on PRs from forks where token may not be available
fail_ci_if_error: ${{ github.event_name == 'push' }}
verbose: true
# Stage 4: SonarCloud Analysis (depends on test)
# Only runs on push to master/main when SONAR_TOKEN is available
# Skipped for PRs from forks where secrets are not accessible
sonarcloud:
name: SonarCloud Analysis
runs-on: ubuntu-latest
needs: test
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main') && github.repository == '0x524a/onvif-go'
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Full history for accurate blame information
- name: Download coverage reports
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: coverage-reports
- name: Verify coverage file
run: |
echo "📁 Downloaded files:"
ls -la
if [ -f coverage.out ]; then
echo "✅ Coverage file found"
head -5 coverage.out
else
echo "⚠️ Coverage file not found, creating empty one"
echo "mode: atomic" > coverage.out
fi
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@4006f663ecaf1f8093e8e4abb9227f6041f52216 # v3.1.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# Stage 5: Build Verification (depends on test, runs in parallel with sonarcloud)
build:
name: Build Verification
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Go
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go modules
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-${{ env.GO_VERSION }}-
- name: Download dependencies
run: go mod download
- name: Build library
run: go build -v ./...
- name: Build CLI tools
run: |
echo "🔨 Building CLI tools..."
go build -v -o bin/onvif-cli ./cmd/onvif-cli
go build -v -o bin/onvif-quick ./cmd/onvif-quick
go build -v -o bin/onvif-server ./cmd/onvif-server
go build -v -o bin/onvif-diagnostics ./cmd/onvif-diagnostics
echo "✅ All CLI tools built successfully"
# Final status check
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [fmt, lint, test, sonarcloud, build]
if: always()
steps:
- name: Check all jobs status
run: |
if [[ "${{ needs.fmt.result }}" != "success" ]]; then
echo "❌ Format check failed"
exit 1
fi
if [[ "${{ needs.lint.result }}" != "success" ]]; then
echo "❌ Lint check failed"
exit 1
fi
if [[ "${{ needs.test.result }}" != "success" ]]; then
echo "❌ Tests failed"
exit 1
fi
# SonarCloud is optional - only fails if it ran and failed (not if skipped)
if [[ "${{ needs.sonarcloud.result }}" == "failure" ]]; then
echo "❌ SonarCloud analysis failed"
exit 1
fi
if [[ "${{ needs.sonarcloud.result }}" == "skipped" ]]; then
echo "️ SonarCloud analysis skipped (only runs on push to master/main)"
fi
if [[ "${{ needs.build.result }}" != "success" ]]; then
echo "❌ Build verification failed"
exit 1
fi
echo "✅ All CI checks passed successfully!"