Repository navigation
Ensure automated backport commits have verified signatures #2998
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,7 +100,41 @@ for (const targetBranch of branches) { | |
| // Push the backport branch (force to handle updates) | ||
| core.info(`Pushing ${backportBranch} to origin`); | ||
| execSync(`git push --force-with-lease origin ${backportBranch}`, { stdio: 'inherit' }); | ||
|
|
||
|
|
||
| // Re-create each new commit through the Git Data API so the resulting chain shows as "Verified" | ||
| core.info(`Re-creating commits via the Git Data API to get verified signatures`); | ||
| const newCommitShas = execSync(`git log --format=%H ${targetBranch}..${backportBranch}`, { encoding: 'utf-8' }) | ||
| .trim().split('\n').filter(Boolean).reverse(); // oldest -> newest | ||
|
|
||
| // Use the same base that produced the cherry-picked trees. The remote | ||
| // target branch may have advanced since the initial fetch. | ||
| let parentSha = execSync(`git rev-parse ${targetBranch}`, { | ||
| encoding: 'utf-8' | ||
| }).trim(); | ||
|
|
||
| for (const sha of newCommitShas) { | ||
| const treeSha = execSync(`git rev-parse ${sha}^{tree}`, { encoding: 'utf-8' }).trim(); | ||
| const message = execSync(`git log -1 --format=%B ${sha}`, { encoding: 'utf-8' }); | ||
|
|
||
| const { data: newCommit } = await github.rest.git.createCommit({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| message, | ||
| tree: treeSha, | ||
| parents: [parentSha] | ||
| }); | ||
|
Comment on lines
+119
to
+125
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Backport commits lose contributor attribution For contributor-authored changes, Learn moreA Git commit stores an author independently of its message and tree. Cherry-picking normally preserves the original author's name and email. The new API requests send only the message, tree, and parent; the API therefore uses the authenticated identity for author metadata, replacing contributor attribution on every recreated commit. Example: Alice authors a PR commit. The local cherry-pick retains Alice as author, but the recreated backport commit credits the GitHub Actions bot. Recommended fix: Read each cherry-picked commit's author name, email, and date from Git, and pass them in the Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| parentSha = newCommit.sha; | ||
| } | ||
|
|
||
| core.info(`Repointing ${backportBranch} at signed commit ${parentSha}`); | ||
| await github.rest.git.updateRef({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| ref: `heads/${backportBranch}`, | ||
| sha: parentSha, | ||
| force: true | ||
| }); | ||
|
|
||
| // Check if a PR already exists for this backport branch | ||
| const { data: existingPRs } = await github.rest.pulls.list({ | ||
| owner: context.repo.owner, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Unsigned push blocks protected backports
When a backport branch requires signed commits,
git pushrejects the unsigned cherry-picks beforecreateCommitruns. No backport PR is created.Learn more
The workflow creates local cherry-picks and pushes the local branch before the Git Data API signs replacement commits. A signed-commit rule on a backport branch rejects that first push, so execution never reaches commit recreation. The catch handler reports failure instead of creating a backport PR.
Example: A repository applies a signed-commit rule to
backport-*. Cherry-picking PR #42 creates unsigned commits locally. The push ofbackport-42-to-release-25.1is rejected, even though the following API calls would have produced signed commits.Recommended fix: Create the Git Data API commit chain before publishing the branch. Push only a signed ref, or create/update the ref through the API after uploading any missing tree and blob objects; ensure the API can resolve each tree before calling
createCommit.Was this helpful? React with 👍 or 👎 to provide feedback.