Skip to content

Commit

Permalink
Improve backport command (dotnet#51306)
Browse files Browse the repository at this point in the history
GitHub Actions started doing shallow checkouts so we often ran into the case where applying the patch would fail with an error due to the commit blobs not being available:

```
error: sha1 information is lacking or useless (eng/pipelines/common/xplat-setup.yml).
error: could not build fake ancestor
```

Fix this by always checking out the whole history. Since this makes checkout quite slow (~2mins), refactor the action so we post the "Started backporting" comment before doing the checkout so the user isn't confused why nothing happens.
  • Loading branch information
akoeplinger authored Apr 15, 2021
1 parent 6b64618 commit 2e12730
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 21 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,39 @@ jobs:
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/backport to')
runs-on: ubuntu-20.04
steps:
- name: Extract backport target branch
uses: actions/github-script@v3
id: target-branch-extractor
with:
result-encoding: string
script: |
if (context.eventName !== "issue_comment") throw "Error: This action only works on issue_comment events.";
// extract the target branch name from the trigger phrase containing these characters: a-z, A-Z, digits, forward slash, dot, hyphen, underscore
const regex = /\/backport to ([a-zA-Z\d\/\.\-\_]+)/;
target_branch = regex.exec(context.payload.comment.body);
if (target_branch == null) throw "Error: No backport branch found in the trigger phrase.";
return target_branch[1];
- name: Post backport started comment to pull request
uses: actions/github-script@v3
with:
script: |
const backport_start_body = `Started backporting to ${{ steps.target-branch-extractor.outputs.result }}: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${process.env.GITHUB_RUN_ID}`;
await github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: backport_start_body
});
- name: Checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Run backport
uses: ./eng/actions/backport
with:
target_branch: ${{ steps.target-branch-extractor.outputs.result }}
auth_token: ${{ secrets.GITHUB_TOKEN }}
pr_description_template: |
Backport of #%source_pr_number% to %target_branch%
Expand Down
2 changes: 2 additions & 0 deletions eng/actions/backport/action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: 'PR Backporter'
description: 'Backports a pull request to a branch using the "/backport to <branch>" comment'
inputs:
target_branch:
description: 'Backport target branch.'
auth_token:
description: 'The token used to authenticate to GitHub.'
pr_title_template:
Expand Down
23 changes: 2 additions & 21 deletions eng/actions/backport/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,13 @@ async function run() {
const github = require("@actions/github");
const exec = require("@actions/exec");

if (github.context.eventName !== "issue_comment") throw "Error: This action only works on issue_comment events.";

const run_id = process.env.GITHUB_RUN_ID;
const repo_owner = github.context.payload.repository.owner.login;
const repo_name = github.context.payload.repository.name;
const pr_number = github.context.payload.issue.number;
const pr_source_ref = process.env.GITHUB_REF;
const comment_user = github.context.payload.comment.user.login;

let octokit = github.getOctokit(core.getInput("auth_token"));
let target_branch = "";
let octokit = github.getOctokit(core.getInput("auth_token", { required: true }));
let target_branch = core.getInput("target_branch", { required: true });

try {
// verify the comment user is a repo collaborator
Expand All @@ -45,26 +41,11 @@ async function run() {
throw new BackportException(`Error: @${comment_user} is not a repo collaborator, backporting is not allowed.`);
}

// extract the target branch name from the trigger phrase containing these characters: a-z, A-Z, digits, forward slash, dot, hyphen, underscore
console.log(`Extracting target branch`);
const regex = /\/backport to ([a-zA-Z\d\/\.\-\_]+)/;
target_branch = regex.exec(github.context.payload.comment.body)[1];
if (target_branch == null) throw new BackportException("Error: No backport branch found in the trigger phrase.");
try { await exec.exec(`git ls-remote --exit-code --heads origin ${target_branch}`) } catch { throw new BackportException(`Error: The specified backport target branch ${target_branch} wasn't found in the repo.`); }
console.log(`Backport target branch: ${target_branch}`);

// Post backport started comment to pull request
const backport_start_body = `Started backporting to ${target_branch}: https://github.com/${repo_owner}/${repo_name}/actions/runs/${run_id}`;
await octokit.issues.createComment({
owner: repo_owner,
repo: repo_name,
issue_number: pr_number,
body: backport_start_body
});

console.log("Applying backport patch");

await exec.exec(`git -c protocol.version=2 fetch --no-tags --progress --no-recurse-submodules origin ${target_branch} ${pr_source_ref}`);
await exec.exec(`git checkout ${target_branch}`);
await exec.exec(`git clean -xdff`);

Expand Down

0 comments on commit 2e12730

Please sign in to comment.