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
5 changes: 5 additions & 0 deletions .github/workflows/auto-approve.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
# contents: write is required for the gh pr merge --auto step (when using
# the App token). Top-level is contents: read. This setup (with job-level
# scoping and comments) helps the Token-Permissions Scorecard check.
# See also the dedicated dependabot-auto-merge.yaml (pull_request_target)
# which handles Dependabot exclusively.
contents: write
pull-requests: write
if: >
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/backport.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
backport:
name: Backport
permissions:
# contents:write + pull-requests:write required by backport-action to create
# backport PRs. Scoped to job level.
contents: write
pull-requests: write
runs-on: ${{ vars.RUNNER || 'ubuntu-latest' }}
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/dco.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ jobs:
echo "Skipping bot commit $sha ($author)"
continue
fi
# Skip merge commits (multiple parents). We squash-merge PRs (including
# Dependabot ones), so merge commits created when updating a branch
# (e.g. via GitHub "Update branch" button) are transient. Skipping them
# reduces babysitting while preserving DCO for real changes. This helps
# maintain high Scorecard scores without unnecessary friction.
num_parents=$(git log -1 --format=%P "$sha" | wc -w)
if [ "$num_parents" -gt 1 ]; then
echo "Skipping merge commit $sha"
continue
fi
if ! git log -1 --format='%B' "$sha" | grep -qE '^Signed-off-by: .+ <.+>'; then
missing+=("$sha")
fi
Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/dependabot-auto-merge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ jobs:
auto-merge:
name: Auto-merge Dependabot PRs
permissions:
# contents:write + pull-requests:write required for gh pr review + gh pr merge --auto.
# This is the minimum for the auto-merge functionality on pull_request_target.
# See Scorecard Token-Permissions: writes are justified here but kept scoped to the job.
contents: write
pull-requests: write
runs-on: ubuntu-latest
Expand Down Expand Up @@ -54,4 +57,9 @@ jobs:
# checks reported" limbo. With strict_required_status_checks_policy
# disabled in the branch ruleset, PRs can merge when behind main, so
# auto-rebase is unnecessary. Dependabot handles its own rebases when
# conflicts arise.
# conflicts arise.
#
# See AGENTS.md "Handling Dependabot PRs" for the supported process
# (always rebase cleanly when helping a PR; the DCO workflow skips merge
# commits to avoid blocking legitimate updates). This design protects
# our high Scorecard scores (CI-Tests=10, Branch-Protection, etc.).
2 changes: 2 additions & 0 deletions .github/workflows/sign-old-releases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
# contents:write + id-token:write required for cosign signing + gh release upload.
# This is a manual workflow_dispatch job (not automatic on PRs).
contents: write
id-token: write
steps:
Expand Down
43 changes: 43 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,49 @@ The repository enforces semantic PR titles via [.github/workflows/pr-title.yaml]

When creating branches, commits, or PRs, make the first line a valid semantic title so the gate passes on the first attempt. This avoids immediate CI failures and repeated title edits.

### Handling Dependabot PRs (Scorecard hygiene + minimal babysitting)

Dependabot PRs (#348, #349 etc.) are important for **Dependency-Update-Tool (10)** and overall supply-chain health on Scorecard. We keep high scores on **CI-Tests (10)**, **Branch-Protection (currently 8)**, **Token-Permissions**, and DCO-related hygiene by ensuring:

- Every Dependabot change still runs (and must pass) the full relevant CI.
- DCO is enforced on real changes.
- We avoid patterns that regress Branch-Protection or CI-Tests.

**How to help an open Dependabot PR without hurting Scorecard or creating more work:**

1. **Never merge `main` into the dependabot branch** (or click "Update branch" if it produces a merge commit). Merge commits have non-bot authors and lack `Signed-off-by`, so they fail DCO even though the bot commit itself is skipped.
2. **Always rebase cleanly** (use the helper for convenience):
```bash
scripts/rebase-dependabot.sh 348
# or
scripts/rebase-dependabot.sh origin/dependabot/...
```
Or manually:
```bash
git fetch origin
git checkout -B temp-dependabot origin/dependabot/...
git rebase origin/main
git push origin HEAD:dependabot/... --force-with-lease
```
3. The DCO workflow now explicitly skips merge commits (in addition to `[bot]` authors) so that occasional update accidents don't block PRs, while the meaningful diff commit still satisfies the spirit of the rule.
4. After a clean rebase/push, new workflow runs will use the latest workflow definitions (important for auto-approve paths).
5. Let the existing "Auto-merge Dependabot PRs" + "Auto Approve" jobs do their work once CI is green. They set `--auto --squash`.
6. If the PR is behind and you want it to move faster, the rebase above + `gh pr comment` or just wait is preferred over broad CI skips.

**Why this protects the best possible Scorecard:**

- CI-Tests stays at 10 only if real tests run on the changes that get merged.
- Branch-Protection already requires up-to-date branches + status checks on main.
- Adding broad skips or risky auto-rebase jobs (GITHUB_TOKEN pushes don't retrigger workflows reliably) has historically caused "limbo" states and lower effective scores.
- Token-Permissions warnings are minimized by scoping writes only where gh commands truly need them (see the dependabot-auto-merge and auto-approve jobs).

See also:
- `.github/workflows/dependabot-auto-merge.yaml` (the NOTE about the removed rebase job)
- `.github/workflows/dco.yaml` (bot + merge-commit skips)
- `pr-title.yaml` (Dependabot is exempted from semantic title)

When in doubt, prefer letting Dependabot open a fresh PR on conflict rather than force-updating an old one.

### Issue closure in PR descriptions

Before running `gh pr create`, check open issues and include `Closes #N`
Expand Down
53 changes: 53 additions & 0 deletions scripts/rebase-dependabot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
#
# rebase-dependabot.sh
#
# Cleanly rebases a Dependabot branch onto latest main and force-pushes with lease.
# This is the supported way to "update" a Dependabot PR without introducing
# merge commits that trip DCO.
#
# Usage:
# scripts/rebase-dependabot.sh origin/dependabot/go_modules/foo-abc123
# scripts/rebase-dependabot.sh 348 # PR number (uses gh)
#
# Why this matters for Scorecard:
# - Preserves CI-Tests=10 (fresh runs after rebase)
# - Avoids weakening Branch-Protection or DCO hygiene
# - See AGENTS.md "Handling Dependabot PRs"
#
set -euo pipefail

TARGET="${1:-}"

if [[ -z "$TARGET" ]]; then
echo "Usage: $0 <branch-ref-or-PR-number>"
echo " e.g. $0 origin/dependabot/..."
echo " $0 348"
exit 1
fi

if [[ "$TARGET" =~ ^[0-9]+$ ]]; then
# Treat as PR number
echo "Resolving PR #$TARGET ..."
BRANCH=$(gh pr view "$TARGET" --json headRefName --jq .headRefName)
echo "Branch: $BRANCH"
else
BRANCH="$TARGET"
fi

echo "Fetching..."
git fetch origin

LOCAL_BRANCH="rebase-dependabot-$(date +%s)"

echo "Checking out clean worktree for $BRANCH ..."
git checkout -B "$LOCAL_BRANCH" "$BRANCH"

echo "Rebasing onto origin/main ..."
git rebase origin/main

echo "Pushing with --force-with-lease ..."
git push origin "HEAD:$BRANCH" --force-with-lease

echo "Done. New head pushed. Workflows will re-run with current definitions."
echo "Delete local branch with: git branch -D $LOCAL_BRANCH"
Loading