From 35122ccd212f0a2cba6e6b6c7e7ae5c3ff2fac40 Mon Sep 17 00:00:00 2001 From: Karol Szwaj Date: Mon, 9 Feb 2026 12:29:48 +0100 Subject: [PATCH 1/2] gh: add /cherry-pick comment for release Signed-off-by: Karol Szwaj --- .github/workflows/cherry-pick.yaml | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 .github/workflows/cherry-pick.yaml diff --git a/.github/workflows/cherry-pick.yaml b/.github/workflows/cherry-pick.yaml new file mode 100644 index 0000000000..6182a39166 --- /dev/null +++ b/.github/workflows/cherry-pick.yaml @@ -0,0 +1,76 @@ +name: Manual Cherry-Pick +on: + issue_comment: + types: [created] + +jobs: + cherry-pick: + # Only trigger if the comment starts with /cherry-pick on a Pull Request + if: contains(github.event.comment.body, '/cherry-pick') && github.event.issue.pull_request + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Parse Branch and PR Data + id: data + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + TARGET_BRANCH=$(echo "${{ github.event.comment.body }}" | sed -n 's|.*/cherry-pick ||p' | xargs) + echo "target_branch=$TARGET_BRANCH" >> $GITHUB_OUTPUT + + # 2. Get original PR title and merge status + PR_JSON=$(gh pr view ${{ github.event.issue.number }} --json title,merged,mergeCommit) + + IS_MERGED=$(echo "$PR_JSON" | jq -r '.merged') + if [ "$IS_MERGED" != "true" ]; then + gh pr comment ${{ github.event.issue.number }} --body "⚠️ Cannot cherry-pick. This PR must be merged first." + exit 1 + fi + + ORIGINAL_TITLE=$(echo "$PR_JSON" | jq -r '.title') + SHA=$(echo "$PR_JSON" | jq -r '.mergeCommit.oid') + + echo "original_title=$ORIGINAL_TITLE" >> $GITHUB_OUTPUT + echo "sha=$SHA" >> $GITHUB_OUTPUT + + - name: Git Config + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Create Cherry-Pick PR + id: create_pr + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TARGET_BRANCH: ${{ steps.data.outputs.target_branch }} + ORIGINAL_TITLE: ${{ steps.data.outputs.original_title }} + COMMIT_SHA: ${{ steps.data.outputs.sha }} + run: | + # Sanitize branch name for the local 'head' branch (replace / with -) + SAFE_NAME=$(echo "$TARGET_BRANCH" | tr '/' '-') + NEW_BRANCH="cherry-pick-$COMMIT_SHA-to-$SAFE_NAME" + + git checkout -b "$NEW_BRANCH" "origin/$TARGET_BRANCH" + + if git cherry-pick "$COMMIT_SHA"; then + git push origin "$NEW_BRANCH" + + # Formulate the new title: [release/v1.7] Original Title + NEW_TITLE="[$TARGET_BRANCH] $ORIGINAL_TITLE" + + gh pr create \ + --title "$NEW_TITLE" \ + --body "Automated cherry-pick of $COMMIT_SHA to $TARGET_BRANCH. Triggered by @${{ github.actor }}." \ + --base "$TARGET_BRANCH" \ + --head "$NEW_BRANCH" + + echo "success=true" >> $GITHUB_OUTPUT + else + gh pr comment ${{ github.event.issue.number }} --body "❌ Cherry-pick to \`$TARGET_BRANCH\` failed due to merge conflicts." + exit 1 + fi From 591b02ddbe1395fbc4f2c703e40d4f0a45f9cc5b Mon Sep 17 00:00:00 2001 From: Karol Szwaj Date: Mon, 9 Feb 2026 13:00:05 +0100 Subject: [PATCH 2/2] gh: check the OWNERS Signed-off-by: Karol Szwaj --- .github/workflows/cherry-pick.yaml | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cherry-pick.yaml b/.github/workflows/cherry-pick.yaml index 6182a39166..e40254947a 100644 --- a/.github/workflows/cherry-pick.yaml +++ b/.github/workflows/cherry-pick.yaml @@ -2,7 +2,6 @@ name: Manual Cherry-Pick on: issue_comment: types: [created] - jobs: cherry-pick: # Only trigger if the comment starts with /cherry-pick on a Pull Request @@ -15,15 +14,34 @@ jobs: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Status + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ACTOR="${{ github.actor }}" + + # Check if actor is listed anywhere in the OWNERS file + if ! grep -i "^- $ACTOR$" OWNERS > /dev/null; then + gh pr comment ${{ github.event.issue.number }} --body "❌ Only people listed in the OWNERS file can use the cherry-pick command." + exit 1 + fi + - name: Parse Branch and PR Data id: data env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - TARGET_BRANCH=$(echo "${{ github.event.comment.body }}" | sed -n 's|.*/cherry-pick ||p' | xargs) + # Extract only the first argument after /cherry-pick (ignore trailing text) + TARGET_BRANCH=$(echo "${{ github.event.comment.body }}" | awk '/\/cherry-pick/{print $2}') + + if [ -z "$TARGET_BRANCH" ]; then + gh pr comment ${{ github.event.issue.number }} --body "⚠️ Usage: \`/cherry-pick \` (e.g. \`/cherry-pick release/v1.7\`)" + exit 1 + fi + echo "target_branch=$TARGET_BRANCH" >> $GITHUB_OUTPUT - # 2. Get original PR title and merge status + # Get original PR title and merge status PR_JSON=$(gh pr view ${{ github.event.issue.number }} --json title,merged,mergeCommit) IS_MERGED=$(echo "$PR_JSON" | jq -r '.merged')