Consumer repositories should add this repository as a top-level submodule:
git submodule add https://github.com/daos-do/code-checking code_checking
git submodule update --init --recursiveConsumer repositories keep local wrappers and workflow files and call shared
scripts from code_checking/.
For bootstrap and validation flows, use the consumer sync command after adding
the submodule, updating it, or changing code-checking-ref.
Linux/macOS:
./code_checking/bin/sync-consumer.shPowerShell equivalent:
pwsh -File .\code_checking\bin\sync-consumer.ps1To skip README updates for a specific run:
Linux/macOS:
./code_checking/bin/sync-consumer.sh --skip-readmePowerShell equivalent:
pwsh -File .\code_checking\bin\sync-consumer.ps1 -SkipReadmeSee README.md for details on what sync-consumer does.
Optionally, you can manually sync or validate the recommended GitHub workflows
(see README.md for details on setup-github-workflow.sh).
After the bootstrap commands above have run, stage only the consumer-side
files for the initial commit. Do not stage the code_checking submodule
pointer if it is currently checked out at a PR or test ref.
First verify the submodule pointer is at origin/main:
# Should match:
git -C code_checking rev-parse HEAD
git ls-remote origin refs/heads/main | awk '{print $1}'If the submodule is at a test ref, reset it to origin/main before
committing:
git -C code_checking fetch origin
git submodule update --remote code_checkingFor the staging and commit details, see README.md.
Do not stage code-checking-ref for normal integration commits. It will
usually remain visible in git status as an untracked file. The pre-commit
guard hook blocks accidental commits of it. An intentional validation PR may
track it temporarily when testing a code_checking PR ref.
There are two distinct cases: updating to a force-pushed code_checking PR branch while testing it locally, and updating the submodule to a new main tip after a merge.
This is the case where you have code-checking-ref set to a PR branch
and that PR was force-pushed. git submodule update --remote is not
sufficient here because it does not know to reset to the new force-pushed
commits; you need to fetch and hard-reset.
- Find the branch name in
code-checking-ref.
cat code-checking-ref
# example output: sre-3706-codespell- Fetch the updated branch from the submodule remote.
git -C code_checking fetch origin sre-3706-codespell- Reset the submodule checkout to the fetched branch tip.
git -C code_checking reset --hard origin/sre-3706-codespell- Verify git status.
git status
# modified: code_checking (new commits) <-- do not stage thisThe submodule will show as modified (new commits), but do not stage or commit it. Keep the submodule pointer at the commit already recorded in the consumer PR.
- If the code_checking PR changed linter/tool requirements or branch policy checks, regenerate consumer workflows.
./code_checking/bin/setup-github-workflow.sh --apply- Stage and commit only changed workflow files.
git add .github/workflows/
git commit --amend --no-verifyUse --no-verify only if your consumer PR intentionally tracks
code-checking-ref and the guard hook fires on it.
The --no-verify bypass is acceptable here because the guard hook is
protecting against accidental commits; the PR is intentional.
For routine updates to a new main tip, see README.md.
For background on submodule update behavior and remote-tracking refs, see the official Git documentation:
This document currently defines workflow behavior for GitHub Actions only. Jenkins-specific behavior is intentionally out of scope.
For consumer repositories, the convention is:
- Default: use the tip of
mainforcode_checking. - Optional override: allow a root file named
code-checking-refto temporarily select a PR ref or specific commit for validation. In normal use it remains untracked locally; in an intentional validation PR it may be tracked temporarily. - Do not require pinning
code_checkingto a specific commit in the consumer repository for normal operation.
This policy minimizes cross-repository update churn while still allowing pre-merge validation when needed.
Local pre-commit runs use the same desired-ref policy. They verify (without
changing files) that code_checking is checked out at the commit resolved from
code-checking-ref (or origin/main when the file is absent).
For consumers using pre-commit hooks, ensure pre-commit is installed:
# macOS (Homebrew)
brew install pre-commit
# Debian/Ubuntu
sudo apt-get install pre-commitOn Linux, prefer distro package managers and avoid sudo pip install for
system tools, because it can conflict with distro-managed Python packages.
If local pre-commit hooks are desired, run setup from the consumer repository root:
./code_checking/bin/setup-dev.shPowerShell equivalent:
pwsh -File .\code_checking\bin\setup-dev.ps1This local setup step is not required for GitHub Actions.
setup-dev does not create or update .github/workflows files.
When run from a consumer repository, setup-dev installs hooks in the consumer
repository, not in the code_checking submodule. If
.pre-commit-config.yaml is missing, setup-dev bootstraps a baseline config
that uses ./code_checking hook entrypoints and then installs hooks.
GitHub Actions must fetch submodule contents explicitly in checkout steps.
Use actions/checkout with submodules enabled.
Recommended behavior for consumer workflows:
- Default to
origin/mainforcode_checking - If
code-checking-refexists, resolve and use that ref instead - Do not rely on the commit pinned in the submodule pointer for checks
Example:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: recursive
fetch-depth: 0
- name: Resolve code_checking ref
run: |
REF="origin/main"
if [ -f code-checking-ref ]; then
REF="$(grep -v '^[[:space:]]*#' code-checking-ref |
sed '/^[[:space:]]*$/d' | head -n 1)"
fi
if [ -z "${REF}" ]; then REF="origin/main"; fi
case "${REF}" in
refs/*) FETCH_REF="${REF}" ;;
origin/*) FETCH_REF="refs/heads/${REF#origin/}" ;;
pull/*/head|pull/*/merge) FETCH_REF="refs/${REF}" ;;
*) FETCH_REF="refs/heads/${REF}" ;;
esac
git -C ./code_checking fetch origin "${FETCH_REF}"
git -C ./code_checking checkout FETCH_HEADRecommended guardrail for consumer repositories:
- Use the same guard script in both pre-commit and GitHub Actions:
./code_checking/checks/guard-code-checking-ref.sh. - Add a Jenkins landing guard in GitHub Actions:
./code_checking/checks/guard-jenkins-library-pin.sh. - Add guard steps in the same workflow job that runs shared checks.
- Let guards record failure without stopping later checks, then fail the job at the end if the guard tripped.
- Require only that single stable checks job in repository rules.
Example step:
./code_checking/checks/guard-code-checking-ref.sh --target-root .
./code_checking/checks/guard-jenkins-library-pin.sh --target-root .This allows normal local override usage while still allowing intentional
validation PRs that temporarily track code-checking-ref, without hiding the
results of later checks. It also blocks active Jenkins shared-library
references such as @Library("my-shared-lib") _ from landing. Guards still
leave the final job status failed so the PR cannot merge accidentally.
Example GitHub Actions job:
jobs:
basic-source-checks:
name: Basic Source checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: recursive
fetch-depth: 0
- name: Resolve code_checking ref
run: |
REF="origin/main"
if [ -f code-checking-ref ]; then
REF="$(grep -v '^[[:space:]]*#' code-checking-ref |
sed '/^[[:space:]]*$/d' | head -n 1)"
fi
if [ -z "${REF}" ]; then REF="origin/main"; fi
case "${REF}" in
refs/*) FETCH_REF="${REF}" ;;
origin/*) FETCH_REF="refs/heads/${REF#origin/}" ;;
pull/*/head|pull/*/merge) FETCH_REF="refs/${REF}" ;;
*) FETCH_REF="refs/heads/${REF}" ;;
esac
git -C ./code_checking fetch origin "${FETCH_REF}"
git -C ./code_checking checkout FETCH_HEAD
- name: Block tracked code-checking-ref
id: guard_code_checking_ref
continue-on-error: true
run: |
bash ./code_checking/checks/guard-code-checking-ref.sh \
--target-root .
- name: Block active Jenkins @Library reference
id: guard_jenkins_library_pin
continue-on-error: true
run: |
bash ./code_checking/checks/guard-jenkins-library-pin.sh \
--target-root .
- name: Verify executable modes
run: |
bash ./code_checking/checks/verify-executable-modes.sh \
--target-root .
- name: Run shared linters
run: bash ./code_checking/bin/run-linters.sh
- name: Fail if any guard check failed
if: >-
${{ always() &&
(steps.guard_code_checking_ref.outcome == 'failure' ||
steps.guard_jenkins_library_pin.outcome == 'failure') }}
run: exit 1Configure branch protection to require the shared checks before merging.
Locate the ruleset configuration in your consumer repository:
- Navigate to repository Settings (gear icon in top-right menu).
- Look for "Branches" or "Rules" in the left sidebar. GitHub has two
overlapping systems:
- Branches (older): Protection rules per-branch
- Rules (newer): Rulesets with target patterns
- If both exist, prefer Rules (rulesets) for new configurations.
Create or edit the rule for your merge branch (for example main):
- Create a new ruleset or branch protection rule for your merge branch.
- Configure the following under "Status checks":
- Required status check: Select
Basic Source checks(from shared workflow) - Rulesets: appears under "Require status checks to pass"
- Branch protection: appears under "Require status checks to pass before merging"
- Required status check: Select
- (Optional) Enable other protections:
- Pull Request Reviews: "Require a pull request before merging"
- Dismiss stale reviews: Reviews approved before a commit is pushed are dismissed
- Require review from code owners: If you maintain
CODEOWNERS
- Save the rule.
Verification:
Once configured, attempts to merge a PR will fail with:
- "
Basic Source checks– required check"
if any check steps fail (guard, executable modes, or linters).
Optional test (guard behavior):
- Create a test PR that intentionally tracks
code-checking-ref - Verify merge is blocked by the required check
To validate override behavior locally, bypass pre-commit checks with:
git commit --no-verifyThe required GitHub check still prevents accidental merge to your protected branch.
When validating a code_checking pull request from a consumer repository,
create or update code-checking-ref in the consumer repository root with the
desired ref value.
Supported values can be any ref accepted by git checkout, such as:
origin/mainpull/123/headfeature/some-branch- a commit SHA
Suggested validation flow:
- Set
code-checking-refto the PR ref (for examplepull/123/head). - Run
./code_checking/bin/sync-consumer.shfrom the consumer repo root. - Commit the resulting consumer-repo changes if needed (for example workflow updates or submodule pointer changes).
- Run checks and validate behavior.
PowerShell equivalent:
pwsh -File .\code_checking\bin\sync-consumer.ps1Local pre-commit validation uses the same ref value. If you need a manual fallback, sync your local checkout first:
REF="$(grep -v '^[[:space:]]*#' code-checking-ref |
sed '/^[[:space:]]*$/d' | head -n 1)"
if [ -z "$REF" ]; then REF="origin/main"; fi
git -C code_checking fetch origin "$REF"
git -C code_checking checkout FETCH_HEADPowerShell equivalent:
$ref = 'origin/main'
if (Test-Path -LiteralPath code-checking-ref) {
foreach ($line in Get-Content -LiteralPath code-checking-ref) {
$trimmed = $line.Trim()
if (-not $trimmed) { continue }
if ($trimmed.StartsWith('#')) { continue }
$ref = $trimmed
break
}
}
git -C code_checking fetch origin $ref
git -C code_checking checkout FETCH_HEADExample workflow step after checkout:
if [ -f code-checking-ref ]; then
REF="$(cat code-checking-ref)"
git -C code_checking fetch origin "$REF"
git -C code_checking checkout FETCH_HEAD
else
git -C code_checking fetch origin main
git -C code_checking checkout origin/main
fiNo consumer repository commit is required to return to normal operation if the override file is not tracked.
To return to default behavior after validation:
- Remove
code-checking-ref(or set it toorigin/main). - Re-run the GitHub workflow.
- Confirm the workflow uses
origin/mainforcode_checking.