From a280e16b57ed652de9f7961eccf6fffe119d14ed Mon Sep 17 00:00:00 2001 From: Martin Wimpress Date: Thu, 19 Mar 2026 15:17:58 +0000 Subject: [PATCH 1/2] ci: consolidate CI/CD workflows into unified builder pipeline - Replace separate build and release workflows with builder.yml - Add lint-code job with golangci-lint, gocyclo, ineffassign checks - Add lint-actions job for workflow validation - Add coverage job with robherley/go-test-action - Add security job with dependency review and govulncheck - Add sentinel job to orchestrate and gate build on prior jobs - Build and release jobs depend on sentinel success - Add concurrency group and cancel-in-progress settings - Update dependabot.yml: change intervals, add groups, format cleanup - Fix .golangci.yml: change third_party regex from $ to / Signed-off-by: Martin Wimpress --- .github/dependabot.yml | 27 ++-- .github/workflows/build.yml | 70 --------- .github/workflows/builder.yml | 278 ++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 131 ---------------- .golangci.yml | 4 +- 5 files changed, 298 insertions(+), 212 deletions(-) delete mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/builder.yml delete mode 100644 .github/workflows/release.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 174aaf7..145da1c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,14 +1,23 @@ -# See the documentation for all configuration options: -# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file - version: 2 updates: - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: github-actions + directories: + - / schedule: - interval: "weekly" + interval: monthly + groups: + github-actions: + patterns: + - "*" - - package-ecosystem: "gomod" - directory: "/" + - package-ecosystem: gomod + directory: / schedule: - interval: "weekly" + interval: weekly + groups: + gomod: + patterns: + - "*" + commit-message: + prefix: "deps" + include: "scope" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 7a94171..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Build - -on: - push: - branches: [ main ] - paths: - - '**.go' - - 'go.mod' - - 'go.sum' - - '.github/workflows/build.yml' - pull_request: - branches: [ main ] - paths: - - '**.go' - - 'go.mod' - - 'go.sum' - - '.github/workflows/build.yml' - workflow_dispatch: - -jobs: - build: - name: Build ${{ matrix.os }} ${{ matrix.arch }} - runs-on: ${{ matrix.runner }} - strategy: - matrix: - include: - - os: linux - arch: amd64 - runner: ubuntu-24.04 - - os: linux - arch: arm64 - runner: ubuntu-24.04-arm - - os: darwin - arch: amd64 - runner: macos-15-intel - - os: darwin - arch: arm64 - runner: macos-15 - fail-fast: false - - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - submodules: recursive - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version-file: go.mod - - - name: Download ffmpeg-statigo libraries - run: | - cd third_party/ffmpeg-statigo - go run ./cmd/download-lib - - - name: Run tests - run: go test -v ./... - - - name: Build ${{ matrix.os }} ${{ matrix.arch }} - run: | - echo "Building for ${{ matrix.os }}/${{ matrix.arch }}..." - go build -v -o jivefire-${{ matrix.os }}-${{ matrix.arch }} ./cmd/jivefire - ls -lh jivefire-${{ matrix.os }}-${{ matrix.arch }} - - - name: Upload artifact - uses: actions/upload-artifact@v7 - with: - name: jivefire-${{ matrix.os }}-${{ matrix.arch }} - path: jivefire-${{ matrix.os }}-${{ matrix.arch }} diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml new file mode 100644 index 0000000..1710467 --- /dev/null +++ b/.github/workflows/builder.yml @@ -0,0 +1,278 @@ +name: Builder ๐Ÿ‘ท + +on: + push: + branches: [main] + tags: ["*.*.*"] + pull_request: + branches: [main] + schedule: + - cron: "0 9 * * 0" # Weekly + workflow_dispatch: + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + lint-code: + name: Lint Code ๐Ÿงน + runs-on: ubuntu-slim + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - run: go vet ./... + - name: Check cyclomatic complexity + run: | + go install github.com/fzipp/gocyclo/cmd/gocyclo@latest + gocyclo -top 20 -ignore '_test\.go$' -avg . + - name: Check ineffectual assignments + run: | + go install github.com/gordonklaus/ineffassign@latest + ineffassign ./... + - uses: golangci/golangci-lint-action@v9 + + lint-actions: + name: Lint Action โš™๏ธ + runs-on: ubuntu-slim + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + - uses: freerangebytes/setup-actionlint@v0.1.1 + - name: Run actionlint + run: | + echo "::add-matcher::.github/actionlint-matcher.json" + actionlint -color + + coverage: + name: Coverage ๐Ÿ“Š + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - name: Download ffmpeg-statigo libraries + run: | + cd third_party/ffmpeg-statigo + go run ./cmd/download-lib + - uses: robherley/go-test-action@v0 + with: + testArguments: -coverprofile=coverage.out -covermode=atomic ./... + omit: untested + + test: + name: Test ๐Ÿงช + strategy: + fail-fast: false + matrix: + include: + - os: linux + arch: amd64 + runner: ubuntu-24.04 + - os: linux + arch: arm64 + runner: ubuntu-24.04-arm + - os: darwin + arch: amd64 + runner: macos-15-intel + - os: darwin + arch: arm64 + runner: macos-15 + runs-on: ${{ matrix.runner }} + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - name: Download ffmpeg-statigo libraries + run: | + cd third_party/ffmpeg-statigo + go run ./cmd/download-lib + - name: Test + run: go test ./... + + security: + name: Security ๐Ÿ”’ + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + security-events: write + steps: + - uses: actions/checkout@v6 + with: + submodules: recursive + - uses: actions/dependency-review-action@v4 + if: github.event_name == 'pull_request' + with: + fail-on-severity: moderate + allow-licenses: 0BSD, AFL-2.0, AFL-2.1, AFL-3.0, ANTLR-PD, ANTLR-PD-fallback, Apache-2.0, Artistic-2.0, BlueOak-1.0.0, BSD-1-Clause, BSD-2-Clause, BSD-2-Clause-FreeBSD, BSD-2-Clause-NetBSD, BSD-2-Clause-Patent, BSD-2-Clause-Views, BSD-3-Clause, BSD-3-Clause-Attribution, BSD-3-Clause-Clear, BSD-3-Clause-HP, BSD-3-Clause-LBNL, BSD-3-Clause-Modification, BSD-3-Clause-No-Nuclear-License-2014, BSD-3-Clause-No-Nuclear-Warranty, BSD-3-Clause-Open-MPI, BSD-3-Clause-Sun, BSD-Source-Code, BSL-1.0, bzip2-1.0.5, bzip2-1.0.6, CC0-1.0, CNRI-Python-GPL-Compatible, curl, ECL-2.0, FTL, GPL-2.0-or-later, GPL-3.0-only, GPL-3.0-or-later, HPND-Fenneberg-Livingston, HPND-sell-regexpr, HTMLTIDY, ICU, ImageMagick, Info-ZIP, Intel, Intel-ACPI, ISC, JasPer-2.0, LGPL-2.1-only, LGPL-2.1-or-later, LGPL-3.0-only, LGPL-3.0-or-later, Libpng, libpng-2.0, libtiff, Linux-OpenIB, LZMA-SDK-9.22, MIT, MIT-0, MIT-advertising, MIT-CMU, MIT-Modern-Variant, MIT-open-group, MITNFA, MPL-2.0, MulanPSL-1.0, MulanPSL-2.0, Multics, NCSA, Net-SNMP, NetCDF, NIST-Software, NTP, OLDAP-2.7, OLDAP-2.8, PostgreSQL, PSF-2.0, SGI-B-2.0, SHL-0.5, Spencer-99, SunPro, TCL, TCP-wrappers, UCAR, Unicode-DFS-2015, Unicode-DFS-2016, UnixCrypt, Unlicense, UPL-1.0, W3C, X11, XFree86-1.1, Xnet, Zlib, zlib-acknowledgement, ZPL-2.0, ZPL-2.1 + fail-on-scopes: runtime + comment-summary-in-pr: on-failure + + - name: Run govulncheck + uses: golang/govulncheck-action@master + with: + repo-checkout: false + go-version-file: go.mod + output-format: sarif + output-file: govulncheck.sarif + + - name: Upload SARIF + uses: github/codeql-action/upload-sarif@v4.32.6 + if: always() + with: + sarif_file: govulncheck.sarif + category: govulncheck + + sentinel: + name: Sentinel ๐Ÿ‘๏ธ + needs: [lint-code, lint-actions, coverage, test, security] + if: always() + runs-on: ubuntu-slim + permissions: {} + steps: + - name: Check results + run: | + results='${{ toJSON(needs.*.result) }}' + echo "Job results: ${results}" + if echo "${results}" | jq -e 'any(. == "failure" or . == "cancelled")' > /dev/null 2>&1; then + echo "One or more jobs failed or were cancelled" + exit 1 + fi + echo "All jobs passed" + + build: + name: Build ${{ matrix.os }} ${{ matrix.arch }} + needs: [sentinel] + if: always() && needs.sentinel.result == 'success' + strategy: + fail-fast: false + matrix: + include: + - os: linux + arch: amd64 + runner: ubuntu-24.04 + - os: linux + arch: arm64 + runner: ubuntu-24.04-arm + - os: darwin + arch: amd64 + runner: macos-15-intel + - os: darwin + arch: arm64 + runner: macos-15 + runs-on: ${{ matrix.runner }} + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + submodules: recursive + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + - name: Download ffmpeg-statigo libraries + run: | + cd third_party/ffmpeg-statigo + go run ./cmd/download-lib + - name: Get version + id: version + run: | + VERSION=$(git describe --tags --always --dirty 2>/dev/null || echo "dev") + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "Building jivefire $VERSION for ${{ matrix.os }}/${{ matrix.arch }}" + - name: Build binary + run: | + go build -ldflags="-X main.version=${{ steps.version.outputs.version }}" -o jivefire-${{ matrix.os }}-${{ matrix.arch }} ./cmd/jivefire + - name: Upload artifact + uses: actions/upload-artifact@v7 + with: + name: jivefire-${{ matrix.os }}-${{ matrix.arch }} + path: jivefire-${{ matrix.os }}-${{ matrix.arch }} + + release: + name: Release ๐Ÿ“ฆ + needs: [build] + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Get version from tag + id: version + run: echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + - name: Generate changelog + id: changelog + run: | + PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") + + if [ -n "$PREV_TAG" ]; then + echo "## Changes since $PREV_TAG" > CHANGELOG.md + git log "$PREV_TAG"..HEAD --pretty=format:"* %s (%h)" >> CHANGELOG.md + else + echo "## Initial Release" > CHANGELOG.md + git log --pretty=format:"* %s (%h)" >> CHANGELOG.md + fi + + cat >> CHANGELOG.md << 'NOTES' + + ## Installation + + Download the appropriate binary for your platform below, make it executable, and move it to your PATH: + + ```bash + # Linux (amd64) + chmod +x jivefire-linux-amd64 + sudo mv jivefire-linux-amd64 /usr/local/bin/jivefire + + # macOS (Apple Silicon) + chmod +x jivefire-darwin-arm64 + sudo mv jivefire-darwin-arm64 /usr/local/bin/jivefire + ``` + + ## Checksums + + SHA256 checksums are provided below for verification. + NOTES + + cat CHANGELOG.md + - name: Download all artifacts + uses: actions/download-artifact@v7 + with: + path: artifacts + pattern: jivefire-* + merge-multiple: false + - name: Create release + uses: softprops/action-gh-release@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.version.outputs.version }} + name: Jivefire ${{ steps.version.outputs.version }} + body_path: CHANGELOG.md + draft: false + prerelease: false + files: artifacts/jivefire-*/jivefire-* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index e48e808..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Release - -on: - push: - tags: - - '*.*.*' - -permissions: - contents: write - -jobs: - create-release: - name: Create Release - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - - name: Get version from tag - id: get_version - run: echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" - - - name: Generate changelog - id: changelog - run: | - # Get previous tag - PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "") - - # Generate changelog between tags - if [ -n "$PREV_TAG" ]; then - echo "## Changes since $PREV_TAG" > CHANGELOG.md - git log "$PREV_TAG..HEAD" --pretty=format:"* %s (%h)" >> CHANGELOG.md - else - echo "## Initial Release" > CHANGELOG.md - git log --pretty=format:"* %s (%h)" >> CHANGELOG.md - fi - - # Add release notes - cat >> CHANGELOG.md << 'EOF' - - ## Installation - - Download the appropriate binary for your platform below, make it executable, and move it to your PATH: - - ```bash - # Linux (amd64) - chmod +x jivefire-linux-amd64 - sudo mv jivefire-linux-amd64 /usr/local/bin/jivefire - - # macOS (Apple Silicon) - chmod +x jivefire-darwin-arm64 - sudo mv jivefire-darwin-arm64 /usr/local/bin/jivefire - ``` - - ## Checksums - - SHA256 checksums are provided below for verification. - EOF - - cat CHANGELOG.md - - - name: Create Release - uses: softprops/action-gh-release@v2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ steps.get_version.outputs.version }} - name: Jivefire ${{ steps.get_version.outputs.version }} - body_path: CHANGELOG.md - draft: false - prerelease: false - - build: - name: Build ${{ matrix.os }} ${{ matrix.arch }} - runs-on: ${{ matrix.runner }} - needs: create-release - strategy: - matrix: - include: - - os: linux - arch: amd64 - runner: ubuntu-24.04 - - os: linux - arch: arm64 - runner: ubuntu-24.04-arm - - os: darwin - arch: amd64 - runner: macos-15-intel - - os: darwin - arch: arm64 - runner: macos-15 - fail-fast: false - - steps: - - name: Checkout code - uses: actions/checkout@v6 - with: - fetch-depth: 0 - submodules: recursive - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version-file: go.mod - - - name: Download ffmpeg-statigo libraries - run: | - cd third_party/ffmpeg-statigo - go run ./cmd/download-lib - - - name: Get version from tag - id: get_version - run: echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" - - - name: Build binary - run: | - VERSION=${{ steps.get_version.outputs.version }} - echo "Building jivefire $VERSION for ${{ matrix.os }}/${{ matrix.arch }}" - go build -ldflags="-X main.version=$VERSION" -o jivefire-${{ matrix.os }}-${{ matrix.arch }} ./cmd/jivefire - ls -lh jivefire-${{ matrix.os }}-${{ matrix.arch }} - - - name: Upload Assets to Release - uses: softprops/action-gh-release@v2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ steps.get_version.outputs.version }} - files: | - jivefire-${{ matrix.os }}-${{ matrix.arch }} diff --git a/.golangci.yml b/.golangci.yml index 482acf5..e0c3bd0 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -53,7 +53,7 @@ linters: - legacy - std-error-handling paths: - - third_party$ + - third_party/ - builtin$ - examples$ formatters: @@ -62,6 +62,6 @@ formatters: exclusions: generated: lax paths: - - third_party$ + - third_party/ - builtin$ - examples$ From 269ee9cfa1a20973de68d1e0ec80f27f33841581 Mon Sep 17 00:00:00 2001 From: Martin Wimpress Date: Thu, 19 Mar 2026 15:20:36 +0000 Subject: [PATCH 2/2] ci(fix): add actionlint problem matcher for GitHub Actions Adds GitHub Actions problem matcher configuration to surface actionlint errors and warnings in the workflow logs with proper file location and severity metadata. Signed-off-by: Martin Wimpress --- .github/actionlint-matcher.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/actionlint-matcher.json diff --git a/.github/actionlint-matcher.json b/.github/actionlint-matcher.json new file mode 100644 index 0000000..4613e16 --- /dev/null +++ b/.github/actionlint-matcher.json @@ -0,0 +1,17 @@ +{ + "problemMatcher": [ + { + "owner": "actionlint", + "pattern": [ + { + "regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$", + "file": 1, + "line": 2, + "column": 3, + "message": 4, + "code": 5 + } + ] + } + ] +}