Skip to content

πŸ› fix(crux): cmdlog next_seq advances past terminal unfinished and orphaned commands #35136

πŸ› fix(crux): cmdlog next_seq advances past terminal unfinished and orphaned commands

πŸ› fix(crux): cmdlog next_seq advances past terminal unfinished and orphaned commands #35136

name: DCO squash attribution
# Pre-merge counterpart to dco-post-merge.yml for one specific class (#6798).
#
# The post-merge monitor skips bot-authored commits, so a branch commit both
# authored AND signed off by Copilot passes every check we run today. GitHub's
# squash merge then writes the landing commit with the PULL REQUEST's author -
# a human - while keeping that message and its bot Signed-off-by. The commit
# that reaches the protected branch is therefore a human-authored commit signed
# off by a bot, which is a genuine mismatched-signoff on history that can no
# longer be rewritten. d8f376e8 (the squash of #6796) is exactly this.
#
# This runs at pull_request time because that is the only point where the
# commit is still writable and the contributor can simply re-sign it.
on:
pull_request:
# labeled/unlabeled: the hive's `merge-method/merge` label changes the
# verdict (see PR_MERGE_METHOD below), so the check re-runs when it moves.
# The job runs in full on every event β€” a skipped job would read as a
# pass on a required check.
types: [opened, synchronize, reopened, labeled, unlabeled]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
squash-attribution:
name: Sign-off survives the squash
# Required on v5: keep on the self-hosted pool so a GitHub-hosted runner
# outage does not make otherwise-mergeable PRs impossible to merge.
runs-on: ${{ (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && fromJSON(vars.HIVE_RUNNER_LABELS || '["ubuntu-latest"]') || 'ubuntu-latest' }}
timeout-minutes: 5
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
# The merge commit GitHub synthesises for a PR is not what gets
# squashed; the PR's own commits are. Check those.
ref: ${{ github.event.pull_request.head.sha }}
- name: Self-test the attribution checker
run: bash src/scripts/test-check-squash-signoff-attribution.sh
- name: Make the default branch resolvable
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
set -euo pipefail
# Commits already on the default branch are excluded from the check
# (see the script). Without this ref a sync PR re-flags every commit
# it carries forward, so fetch it explicitly rather than relying on
# checkout having populated remote-tracking refs.
git fetch --no-tags origin \
"+refs/heads/${DEFAULT_BRANCH}:refs/remotes/origin/${DEFAULT_BRANCH}"
git rev-parse --verify "refs/remotes/origin/${DEFAULT_BRANCH}^{commit}" >/dev/null
- name: Check sign-off attribution across the PR's commits
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_AUTHOR_LOGIN: ${{ github.event.pull_request.user.login }}
LANDED_REFS: origin/${{ github.event.repository.default_branch }}
# The hive labels a role/trusted PR whose head mixes the
# contributor's commits with its own self-signed ones and merges it
# with a merge commit; the script then accepts a bot-authored,
# bot-self-signed commit (and nothing else) because nothing is
# squashed. Labels need triage on the repo, so a contributor cannot
# set this themselves.
PR_MERGE_METHOD: ${{ contains(github.event.pull_request.labels.*.name, 'merge-method/merge') && 'merge' || '' }}
run: |
set -euo pipefail
bash src/scripts/check-squash-signoff-attribution.sh \
"${BASE_SHA}" "${HEAD_SHA}" "${PR_AUTHOR_LOGIN}"