Skip to content

Commit

Permalink
tools: add a backport queue cron action
Browse files Browse the repository at this point in the history
  • Loading branch information
aduh95 committed Dec 1, 2024
1 parent 03ec900 commit 38125cf
Showing 1 changed file with 166 additions and 0 deletions.
166 changes: 166 additions & 0 deletions .github/workflows/backport-queue.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
name: Backport Commit Queue

on:
schedule:
- cron: '0 0 * * *' # Every day at midnight
workflow_dispatch:

concurrency: ${{ github.workflow }}

env:
NODE_VERSION: lts/*
PYTHON_VERSION: '3.12'
FLAKY_TESTS: keep_retrying
CC: sccache clang
CXX: sccache clang++
SCCACHE_GHA_ENABLED: 'true'

permissions:
contents: write

jobs:
commitQueue:
runs-on: ubuntu-latest
if: github.repository == 'nodejs/node' || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
branch:
- { release-line: v23.x, base-branch: main }
- { release-line: v22.x, base-branch: v23.x }
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# Needs the whole git history for ncu to work
# See https://github.com/nodejs/node-core-utils/pull/486
fetch-depth: 0
ref: ${{ matrix.branch.release-line }}-staging

- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Set up sccache
uses: mozilla-actions/sccache-action@9e326ebed976843c9932b3aa0e021c6f50310eb4 # v0.0.6
with:
version: v0.8.1

# Install dependencies
- name: Install Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install branch-diff
run: npm install -g branch-diff

- name: Setup git author
run: |
git config --local user.email "[email protected]"
git config --local user.name "Node.js GitHub Bot"
- name: Set up ghauth config (Ubuntu)
run: |
mkdir -p "${XDG_CONFIG_HOME:-~/.config}/changelog-maker"
echo '{}' | jq '{user: env.USERNAME, token: env.TOKEN}' > "${XDG_CONFIG_HOME:-~/.config}/changelog-maker/config.json"
env:
USERNAME: ${{ secrets.JENKINS_USER }}
TOKEN: ${{ github.token }}

- name: Fetch base branch
run: |
git remote set-branches --add origin "$BASE_BRANCH"
git fetch origin "$BASE_BRANCH"
env:
BASE_BRANCH: ${{ matrix.branch.base-branch }}

- name: Fetch auto-backport branch if it exists
id: fetch
run: |
if git fetch origin "$BACKPORT_BRANCH"; then
STAGING_BRANCH_TIP="$(git rev-parse HEAD)"
WORKING_BRANCH_TIP="$(git rev-parse FETCH_HEAD)"
echo "WORKING_BRANCH_TIP=$WORKING_BRANCH_TIP" >> "$GITHUB_OUTPUT"
if [ "$WORKING_BRANCH_TIP" != "$STAGING_BRANCH_TIP" ]; then
git reset "$WORKING_BRANCH_TIP" --hard
git rebase "$STAGING_BRANCH_TIP" --empty=drop || git reset "$STAGING_BRANCH_TIP" --hard
fi
else
echo "Branch doesn't exist yet"
fi
env:
BACKPORT_BRANCH: ${{ matrix.branch.release-line }}-staging-auto-backport

- name: Run the queue
id: queue
run: |
set -xe
backport() (
set -xe
COMMIT="$1"
git cherry-pick "$COMMIT"
NODE="$(command -v node)" make lint-js
make build-ci -j4 V=1 CONFIG_FLAGS="--error-on-warn"
make run-ci -j4 V=1 TEST_CI_ARGS="-p actions --node-args='--test-reporter=spec' --node-args='--test-reporter-destination=stdout' --measure-flakiness 9"
NODE="$(command -v node)" make test-doc "-j${PARALLELIZATION}"
)
[ "$MAX_COMMITS" != "0" ] &&\
branch-diff "${CURRENT_RELEASE_LINE}-staging" "$BASE_REF" \
--exclude-label="semver-major,dont-land-on-${CURRENT_RELEASE_LINE},backport-requested-${CURRENT_RELEASE_LINE},backport-blocked-${CURRENT_RELEASE_LINE},backport-open-${CURRENT_RELEASE_LINE},backported-to-${CURRENT_RELEASE_LINE}"\
--filter-release --format=sha --reverse | while read -r COMMIT ; do
if backport "$COMMIT" 2>&1 >output; then
MAX_COMMITS="$((MAX_COMMITS-1))"
else
{
EOF="$(node -p 'crypto.randomUUID()')"
echo "$COMMIT<<$EOF"
echo "…"
tail output # Cutting the output to avoid exceeding memory.
echo "$EOF"
} >> "$GITHUB_OUTPUT"
git cherry-pick --skip || true
fi
cat output
[ "$MAX_COMMITS" = "0" ] && break
done
rm output
env:
MAX_COMMITS: 9 # backport commits 9 at a time to limit the risk of timeout
CURRENT_RELEASE_LINE: ${{ matrix.branch.release-line }}
BASE_REF: origin/${{ matrix.branch.base-branch }}
BACKPORT_BRANCH: ${{ matrix.branch.release-line }}-staging-auto-backport

- name: Get local HEAD
id: head
run: echo "HEAD=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"

- name: Push to working branch
if: ${{ steps.fetch.outputs.WORKING_BRANCH_TIP != steps.head.outputs.HEAD }}
run: git push origin "HEAD:refs/heads/$BACKPORT_BRANCH" --force
env:
BACKPORT_BRANCH: ${{ matrix.branch.release-line }}-staging-auto-backport

- name: Report errors
if: ${{
steps.fetch.outputs.WORKING_BRANCH_TIP != steps.head.outputs.HEAD &&
toJson(steps.queue.outputs) != '{}'
}}
run: |
node | gh issue create --repo "$GITHUB_REPOSITORY_OWNER/Releast"\
-t "Autobackport is failing on $CURRENT_RELEASE_LINE" --file-body -<<'EOF'
console.log(`Workflow URL: <${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}>`);
console.log('\n<ul>');
for (const {sha, output} of Object.entries(JSON.parse(process.env.FAILED_BACKPORTS))) {
console.log('<li><details>');
console.log(`<summary>${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/commit/${sha}</summary>`);
console.log(`\n${'```'}\n${output}\n${'```'}\n`);
console.log('</details></li>');
}
console.log('</ul>');
EOF
env:
GH_TOKEN: ${{ secrets.GH_USER_TOKEN }}
FAILED_BACKPORTS: ${{ toJson(steps.queue.outputs) }}
CURRENT_RELEASE_LINE: ${{ matrix.branch.release-line }}

0 comments on commit 38125cf

Please sign in to comment.