Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .github/workflows/coverage-go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# SPDX-FileCopyrightText: 2025 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: coverage-go

# Reusable workflow that produces a Go coverage profile, writes the total
# to the job summary, and uploads the profile to Coveralls.
#
# The caller repo must be enrolled in Coveralls; the upload authenticates
# with the automatically-provided GITHUB_TOKEN.

on:
workflow_call:
inputs:
go_version:
description: 'Go version to use (e.g. "1.26.7", "stable"). Mutually exclusive with go_version_file.'
required: false
type: string
go_version_file:
description: 'Path to a go.mod or .go-version file containing the Go version. Mutually exclusive with go_version.'
required: false
type: string
coverage-command:
description: 'Command that writes the coverage profile to `coverage-file`'
required: false
type: string
default: 'go test -coverprofile=coverage.out ./...'
coverage-file:
description: 'Path to the coverage profile written by `coverage-command`'
required: false
type: string
default: 'coverage.out'

permissions:
contents: read # baseline for checkout

jobs:
coverage-go:
name: coverage-go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: ${{ inputs.go_version || (inputs.go_version_file == '' && 'stable' || '') }}
go-version-file: ${{ inputs.go_version_file || '' }}

- name: Run tests with coverage
env:
COVERAGE_COMMAND: ${{ inputs.coverage-command }}
run: eval "$COVERAGE_COMMAND"

- name: Report total coverage
env:
COVERAGE_FILE: ${{ inputs.coverage-file }}
run: |
total=$(go tool cover -func="$COVERAGE_FILE" | awk '/^total:/ {print $3}')
echo "Total coverage: ${total}" | tee -a "$GITHUB_STEP_SUMMARY"

- name: Upload coverage to Coveralls
uses: coverallsapp/github-action@8d6379e14d29928660c4ba802d8e85393440b329 # v2.3.8
with:
file: ${{ inputs.coverage-file }}
format: golang
github-token: ${{ secrets.GITHUB_TOKEN }}
62 changes: 62 additions & 0 deletions .github/workflows/lint-go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# SPDX-FileCopyrightText: 2025 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: lint-go

# Reusable workflow that lints the caller's Go module. Runs golangci-lint,
# and separately verifies go.mod/go.sum are tidy by running the tidy
# command and failing on a dirty diff.
#
# Pair with test-go for the unit-test half of the Go CI wave.

on:
workflow_call:
inputs:
go_version:
description: 'Go version to use (e.g. "1.26.7", "stable"). Mutually exclusive with go_version_file.'
required: false
type: string
go_version_file:
description: 'Path to a go.mod or .go-version file containing the Go version. Mutually exclusive with go_version.'
required: false
type: string
golangci-lint-version:
Comment thread
synackd marked this conversation as resolved.
description: 'golangci-lint release to run'
required: false
type: string
default: 'latest'

permissions:
contents: read # baseline for checkout

jobs:
golangci-lint:
name: golangci-lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: ${{ inputs.go_version || (inputs.go_version_file == '' && 'stable' || '') }}
go-version-file: ${{ inputs.go_version_file || '' }}
- uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
with:
version: ${{ inputs.golangci-lint-version }}

modules:
name: modules
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: ${{ inputs.go_version || (inputs.go_version_file == '' && 'stable' || '') }}
go-version-file: ${{ inputs.go_version_file || '' }}
- name: Check go.mod and go.sum are tidy
run: |
go mod tidy
git diff --exit-code -- go.mod go.sum
34 changes: 34 additions & 0 deletions .github/workflows/reuse.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2025 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: reuse

# Reusable workflow that checks the caller repo for REUSE compliance —
# every file carries a copyright notice and an SPDX license identifier,
# and every referenced license is present under LICENSES/.

on:
workflow_call:
inputs:
reuse_version:
type: string
required: false
default: '6.2.0'
description: 'Reuse CLI version to use (e.g. "6.2.0").'

permissions:
contents: read # baseline for checkout

jobs:
reuse:
name: reuse
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- name: REUSE compliance check
env:
REUSE_VERSION: ${{ inputs.reuse_version }}
run: pipx run --backend pip --spec "reuse==$REUSE_VERSION" reuse lint --lines
51 changes: 51 additions & 0 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# SPDX-FileCopyrightText: 2025 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: scorecard

# Reusable workflow that runs the OpenSSF Scorecard supply-chain analysis
# over the caller repo and uploads the SARIF to GitHub Advanced Security.
#
# On anything other than a pull_request the results are also published to
# the public OpenSSF dashboard, which is what backs the Scorecard badge.
# Callers should trigger this on the default branch, on pull_request, and
# on a schedule; running it on other branches scores an incomplete tree.

on:
workflow_call:

permissions:
contents: read # baseline for checkout
security-events: write # for SARIF upload to GHAS
id-token: write # for publishing results to the OpenSSF dashboard

jobs:
scorecard:
name: scorecard
# Scorecard is a container action and needs a full-fat runner.
runs-on: ubuntu-latest
Comment thread
synackd marked this conversation as resolved.
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- name: Run Scorecard analysis
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
with:
results_file: results.sarif
results_format: sarif
publish_results: ${{ github.event_name != 'pull_request' }}

- name: Upload SARIF artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: scorecard-sarif
path: results.sarif
retention-days: 5

- name: Upload SARIF to GHAS
if: github.event_name != 'pull_request'
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
with:
sarif_file: results.sarif
category: scorecard
46 changes: 46 additions & 0 deletions .github/workflows/test-go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# SPDX-FileCopyrightText: 2025 OpenCHAMI a Series of LF Projects, LLC
# SPDX-License-Identifier: MIT

name: test-go

# Reusable workflow that runs the caller's Go unit tests. Fetches tags so
# tests that assert on version metadata derived from `git describe` behave
# the same as they do locally.

on:
workflow_call:
inputs:
go_version:
description: 'Go version to use (e.g. "1.26.7", "stable"). Mutually exclusive with go_version_file.'
required: false
type: string
go_version_file:
description: 'Path to a go.mod or .go-version file containing the Go version. Mutually exclusive with go_version.'
required: false
type: string
test-command:
description: 'Command that runs the tests'
required: false
type: string
default: 'go test -race ./...'

permissions:
contents: read # baseline for checkout

jobs:
test-go:
name: test-go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
fetch-tags: true
persist-credentials: false
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
go-version: ${{ inputs.go_version || (inputs.go_version_file == '' && 'stable' || '') }}
go-version-file: ${{ inputs.go_version_file || '' }}
- name: Run tests
env:
TEST_COMMAND: ${{ inputs.test-command }}
run: eval "$TEST_COMMAND"
106 changes: 106 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ Reusable GitHub Actions for CI/CD.
- `.github/workflows/release-signed-artifacts.yml`: Publishes a GitHub Release with signed RPMs and public keys
- `.github/workflows/publish-release.yml`: Publishes the draft GitHub Release for a tag
- `.github/workflows/lint-workflows.yml`: Reusable workflow that lints workflow files (actionlint + zizmor)
- `.github/workflows/lint-go.yml`: Reusable workflow that runs golangci-lint and checks go.mod/go.sum are tidy
- `.github/workflows/test-go.yml`: Reusable workflow that runs Go unit tests
- `.github/workflows/coverage-go.yml`: Reusable workflow that reports Go coverage and uploads it to Coveralls
- `.github/workflows/reuse.yml`: Reusable workflow that checks REUSE copyright/licensing compliance
- `.github/workflows/govulncheck.yml`: Reusable workflow that scans Go modules for known CVEs
- `.github/workflows/dependency-review.yml`: Reusable workflow that gates PRs introducing CVE-flagged deps
- `.github/workflows/trivy-image-scan.yml`: Reusable workflow that scans built container images for CVEs
- `.github/workflows/scorecard.yml`: Reusable workflow that runs the OpenSSF Scorecard supply-chain analysis
- `.github/workflows/pr-registry-cleanup.yml`: Deletes the GHCR container images a PR published, once it closes

## Versioning & Usage
Expand Down Expand Up @@ -101,6 +106,83 @@ jobs:
uses: OpenCHAMI/github-actions/.github/workflows/lint-workflows.yml@v3.8
```

### lint-go (Reusable Workflow)
Lints the caller's Go module. Runs `golangci-lint`, and separately verifies `go.mod`/`go.sum` are tidy by running the tidy command and failing on a dirty diff. Uses Go `stable` unless the caller sets `go_version` or `go_version_file`. `golangci-lint` tracks `latest` unless pinned.

**Usage:**
```yaml
name: Lint
on:
pull_request:
push:
branches: [main]

jobs:
lint:
uses: OpenCHAMI/github-actions/.github/workflows/lint-go.yml@v3.9
# Optional overrides:
# with:
# golangci-lint-version: v2.13.2
# go_version_file: go.mod
# tidy-command: make mod
```

### test-go (Reusable Workflow)
Runs the caller's Go unit tests. Fetches tags so tests asserting on `git describe` version metadata behave as they do locally.

**Usage:**
```yaml
name: Test
on:
pull_request:
push:
branches: [main]

jobs:
test:
uses: OpenCHAMI/github-actions/.github/workflows/test-go.yml@v3.9
# Optional overrides:
# with:
# go_version_file: go.mod
# test-command: make test
```

### coverage-go (Reusable Workflow)
Produces a Go coverage profile, writes the total to the job summary, and uploads the profile to Coveralls using the automatically-provided `GITHUB_TOKEN`. The caller repo must be enrolled in Coveralls.

**Usage:**
```yaml
name: Coverage
on:
pull_request:
push:
branches: [main]

jobs:
coverage:
uses: OpenCHAMI/github-actions/.github/workflows/coverage-go.yml@v3.9
# Optional overrides:
# with:
# go_version_file: go.mod
# coverage-command: make coverage
```

### reuse (Reusable Workflow)
Runs the [`reuse`](https://reuse.software) tool over the caller repo via `pipx` to check REUSE compliance: every file carries a copyright notice and an SPDX license identifier, and every referenced license is present under `LICENSES/`. Pins `reuse` 6.2.0.

**Usage:**
```yaml
name: REUSE
on:
pull_request:
push:
branches: [main]

jobs:
reuse:
uses: OpenCHAMI/github-actions/.github/workflows/reuse.yml@v3.9
```

### govulncheck (Reusable Workflow)
Runs the Go team's vulnerability scanner against the caller's module. Detects known CVEs in the import graph (direct and transitive). Reads the Go version from the caller's `go.mod` by default.

Expand Down Expand Up @@ -155,6 +237,30 @@ jobs:
image-ref: ghcr.io/openchami/foo:${{ github.sha }}
```

### scorecard (Reusable Workflow)
Runs the OpenSSF Scorecard supply-chain analysis and uploads SARIF findings to GitHub Advanced Security. Outside of `pull_request` runs it also publishes to the public OpenSSF dashboard, which is what backs the Scorecard badge. Trigger it on the default branch, on PRs, and on a schedule — running it on other branches scores an incomplete tree.

**Usage:**
```yaml
name: Scorecard
on:
branch_protection_rule:
pull_request:
push:
branches: [main]
schedule:
- cron: '39 5 * * 1'

permissions:
contents: read
security-events: write
id-token: write

jobs:
scorecard:
uses: OpenCHAMI/github-actions/.github/workflows/scorecard.yml@v3.9
```

### build-publish-container-goreleaser (Reusable Workflow)
Builds and publishes a container image via GoReleaser, with multi-arch builds, build provenance attestation, and PR snapshot support. Release builds (`is_pr_build: false`) pass GitHub's auto-generated release notes for the pushed tag to GoReleaser via `--release-notes`.

Expand Down