From 856017ca893596d04718d9807f3c5f5568522f76 Mon Sep 17 00:00:00 2001 From: BryanFRD Date: Sun, 25 Oct 2026 11:10:45 +0100 Subject: [PATCH 1/2] ci(dco): add a reusable DCO sign-off workflow and have Renovate sign off Signed-off-by: BryanFRD --- .github/workflows/reusable-dco.yml | 36 ++++++++++++++++++++++++++ default.json | 1 + workflow-templates/README.md | 1 + workflow-templates/dco.properties.json | 7 +++++ workflow-templates/dco.yml | 12 +++++++++ 5 files changed, 57 insertions(+) create mode 100644 .github/workflows/reusable-dco.yml create mode 100644 workflow-templates/dco.properties.json create mode 100644 workflow-templates/dco.yml diff --git a/.github/workflows/reusable-dco.yml b/.github/workflows/reusable-dco.yml new file mode 100644 index 0000000..c9725e0 --- /dev/null +++ b/.github/workflows/reusable-dco.yml @@ -0,0 +1,36 @@ +name: Reusable — DCO sign-off + +on: + workflow_call: + inputs: + runner: + description: 'Override the runner label. Empty (default) auto-selects by repo visibility: private repos use ferrlabs-k8s-light, public repos use ubuntu-latest.' + type: string + required: false + default: '' + +permissions: + contents: read + +jobs: + sign-off: + name: sign-off + runs-on: ${{ inputs.runner != '' && inputs.runner || (github.event.repository.private && 'ferrlabs-k8s-light' || 'ubuntu-latest') }} + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + persist-credentials: false + - name: Every commit needs a Signed-off-by line + env: + BASE_REF: ${{ github.base_ref }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: | + missing=$(git log --no-merges --format='%H %s' --invert-grep --grep='^Signed-off-by: ' \ + "origin/${BASE_REF}..${HEAD_SHA}") + if [ -n "$missing" ]; then + echo "Commits without a sign-off:" + echo "$missing" + echo "Run: git rebase --signoff origin/${BASE_REF}" + exit 1 + fi diff --git a/default.json b/default.json index fe73d51..51f73b9 100644 --- a/default.json +++ b/default.json @@ -7,6 +7,7 @@ "helpers:pinGitHubActionDigests" ], "dependencyDashboard": false, + "commitBody": "Signed-off-by: ferrlabs-renovate[bot] <282300760+ferrlabs-renovate[bot]@users.noreply.github.com>", "rebaseWhen": "conflicted", "recreateWhen": "always", "minimumReleaseAge": "1 day", diff --git a/workflow-templates/README.md b/workflow-templates/README.md index a90ebe0..6c06651 100644 --- a/workflow-templates/README.md +++ b/workflow-templates/README.md @@ -14,6 +14,7 @@ GitHub-discovered workflow templates. They appear under **Actions → New workfl | [`scorecard`](scorecard.yml) | OpenSSF Scorecard supply-chain risk score | All public repos and key private repos. | | [`security-scan`](security-scan.yml) | Reusable: gitleaks (secrets) + osv-scanner (CVE) + trufflehog (deep history) | Every repo — call the shared workflow from `FerrLabs/.github`. | | [`pr-title`](pr-title.yml) | Conventional Commits validation on PR titles | Every repo (mandatory because we squash-merge). | +| [`dco`](dco.yml) | Reusable: every commit of a PR needs a `Signed-off-by` line | Repos that enforce the DCO. | | [`release`](release.yml) | Auto-release on push to main with `FerrLabs/FerrFlow@v7` | Repos that ship semver releases. | | [`docker-publish`](docker-publish.yml) | Reusable: hadolint + multi-arch build + Trivy + cosign keyless + SBOM | Repos that publish a container image. | diff --git a/workflow-templates/dco.properties.json b/workflow-templates/dco.properties.json new file mode 100644 index 0000000..8a3e54d --- /dev/null +++ b/workflow-templates/dco.properties.json @@ -0,0 +1,7 @@ +{ + "name": "FerrLabs — DCO sign-off", + "description": "Fails a PR when one of its commits has no Signed-off-by line. Fix with git rebase --signoff.", + "iconName": "ferrlabs", + "categories": ["Continuous integration"], + "filePatterns": [".*"] +} diff --git a/workflow-templates/dco.yml b/workflow-templates/dco.yml new file mode 100644 index 0000000..f0ce433 --- /dev/null +++ b/workflow-templates/dco.yml @@ -0,0 +1,12 @@ +name: DCO + +on: + pull_request: + types: [opened, edited, synchronize, reopened] + +permissions: + contents: read + +jobs: + sign-off: + uses: FerrLabs/.github/.github/workflows/reusable-dco.yml@main From 5cf300470782224f4c55a5cc6625b2d55fa8a0ed Mon Sep 17 00:00:00 2001 From: BryanFRD Date: Sun, 25 Oct 2026 11:13:06 +0100 Subject: [PATCH 2/2] ci(dco): cancel stale runs per pull request Signed-off-by: BryanFRD --- .github/workflows/reusable-dco.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/reusable-dco.yml b/.github/workflows/reusable-dco.yml index c9725e0..a9f93e7 100644 --- a/.github/workflows/reusable-dco.yml +++ b/.github/workflows/reusable-dco.yml @@ -9,6 +9,10 @@ on: required: false default: '' +concurrency: + group: reusable-dco-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + permissions: contents: read