Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/codex/prompts/analyze-release.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,25 +186,25 @@ Return a JSON object matching the output schema with:
}
},
{
"name": "vectoriadb",
"name": "enclave-vm",
"bump": "patch",
"newVersion": "1.0.1",
"reason": "Fixed memory leak in vector storage",
"newVersion": "2.0.1",
"reason": "Fixed memory leak in sandbox cleanup",
"changelog": {
"added": [],
"changed": [],
"deprecated": [],
"removed": [],
"fixed": ["Fixed memory leak when deleting vectors from namespace"],
"fixed": ["Fixed memory leak when disposing sandbox instances"],
"security": []
}
}
],
"globalChangelog": {
"summary": "Minor updates to ast-guard and vectoriadb",
"summary": "Minor updates to ast-guard and enclave-vm",
"projects": [
{ "name": "ast-guard", "version": "1.1.0", "summary": "Added sanitizeHtml function" },
{ "name": "vectoriadb", "version": "1.0.1", "summary": "Fixed memory leak" }
{ "name": "enclave-vm", "version": "2.0.1", "summary": "Fixed memory leak" }
]
},
"docs": {
Expand Down
288 changes: 288 additions & 0 deletions .github/workflows/cherry-pick-prompt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
name: Cherry-pick to main

on:
pull_request:
types: [closed]

permissions:
contents: write
pull-requests: write
issues: write

concurrency:
group: enclave-cherry-pick-${{ github.event.pull_request.number }}
cancel-in-progress: false

jobs:
cherry-pick:
# Only run when:
# - PR was merged (not just closed)
# - PR is not from a fork (forked PRs have read-only GITHUB_TOKEN)
# - Target branch is a release branch (not main)
if: >
github.event.pull_request.merged == true &&
github.event.pull_request.head.repo.fork == false &&
github.event.pull_request.base.ref != github.event.repository.default_branch &&
(startsWith(github.event.pull_request.base.ref, 'release/') ||
startsWith(github.event.pull_request.base.ref, 'next/'))
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Configure git user
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

- name: Prepare cherry-pick branch
id: prepare
shell: bash
env:
ORIGINAL_BRANCH: ${{ github.event.pull_request.head.ref }}
RELEASE_BRANCH: ${{ github.event.pull_request.base.ref }}
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
set -euo pipefail

# Create cherry-pick branch name
# Sanitize branch name (remove invalid characters, truncate if needed)
CHERRY_BRANCH="${ORIGINAL_BRANCH}-cherry-pick-main"
CHERRY_BRANCH=$(echo "$CHERRY_BRANCH" | sed 's/[^a-zA-Z0-9._/-]/-/g' | head -c 100)

# Validate branch name is valid for git
if ! git check-ref-format --branch "$CHERRY_BRANCH" >/dev/null 2>&1; then
echo "::error::Invalid branch name after sanitization: $CHERRY_BRANCH"
exit 1
fi

echo "cherry_branch=$CHERRY_BRANCH" >> "$GITHUB_OUTPUT"
echo "Cherry-pick branch: $CHERRY_BRANCH"

# Get default branch
DEFAULT_BRANCH="${{ github.event.repository.default_branch }}"

# Checkout default branch (main)
git fetch origin "$DEFAULT_BRANCH"
git checkout "$DEFAULT_BRANCH"
git pull origin "$DEFAULT_BRANCH"

# Create the cherry-pick branch (delete if already exists)
if git show-ref --verify --quiet "refs/heads/$CHERRY_BRANCH"; then
echo "Branch $CHERRY_BRANCH already exists locally, deleting..."
git branch -D "$CHERRY_BRANCH"
fi
if git ls-remote --heads origin "$CHERRY_BRANCH" | grep -q .; then
echo "Branch $CHERRY_BRANCH already exists on remote, deleting..."
git push origin --delete "$CHERRY_BRANCH" || true
fi
git checkout -b "$CHERRY_BRANCH"

# Attempt cherry-pick
echo "Attempting cherry-pick of $MERGE_SHA..."

# Detect if merge commit (has multiple parents)
PARENT_COUNT=$(git rev-list --parents -n1 "$MERGE_SHA" | wc -w)
PARENT_COUNT=$((PARENT_COUNT - 1)) # Subtract the commit itself

CHERRY_PICK_ARGS="--no-commit"
if [ "$PARENT_COUNT" -gt 1 ]; then
echo "Detected merge commit with $PARENT_COUNT parents, using -m 1"
CHERRY_PICK_ARGS="-m 1 --no-commit"
fi

if git cherry-pick $CHERRY_PICK_ARGS "$MERGE_SHA"; then
echo "conflict=false" >> "$GITHUB_OUTPUT"

# Create commit with proper attribution
git commit -m "$(cat <<EOF
Cherry-pick: $PR_TITLE

Cherry-picked from #$PR_NUMBER (merged to $RELEASE_BRANCH)
Original commit: $MERGE_SHA

Co-Authored-By: ${{ github.event.pull_request.user.login }} <${{ github.event.pull_request.user.id }}+${{ github.event.pull_request.user.login }}@users.noreply.github.com>
EOF
)"
echo "Cherry-pick successful"
else
echo "conflict=true" >> "$GITHUB_OUTPUT"
git cherry-pick --abort || true
echo "Cherry-pick failed due to conflicts"
fi

- name: Ensure labels exist
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh label create "cherry-pick" --color "0E8A16" --description "Cherry-picked changes" 2>/dev/null || true
gh label create "auto-cherry-pick" --color "1D76DB" --description "Auto cherry-pick" 2>/dev/null || true
gh label create "conflict" --color "D93F0B" --description "Has conflicts" 2>/dev/null || true
gh label create "needs-attention" --color "FBCA04" --description "Needs attention" 2>/dev/null || true

- name: Push branch and create PR
if: steps.prepare.outputs.conflict == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CHERRY_BRANCH: ${{ steps.prepare.outputs.cherry_branch }}
RELEASE_BRANCH: ${{ github.event.pull_request.base.ref }}
ORIGINAL_PR: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
set -euo pipefail

# Push the cherry-pick branch
git push origin "$CHERRY_BRANCH"

# Create the PR
PR_URL=$(gh pr create \
--base "$DEFAULT_BRANCH" \
--head "$CHERRY_BRANCH" \
--title "Cherry-pick: $PR_TITLE" \
--label "cherry-pick" \
--label "auto-cherry-pick" \
--body "$(cat <<EOF
## Cherry-pick to main

This PR cherry-picks the changes from #$ORIGINAL_PR which was merged to \`$RELEASE_BRANCH\`.

### Original PR
- **PR:** #$ORIGINAL_PR
- **Title:** $PR_TITLE
- **Author:** @$PR_AUTHOR
- **Merged to:** \`$RELEASE_BRANCH\`

### Action Required
Please review this cherry-pick to ensure it applies correctly to \`$DEFAULT_BRANCH\`.

If the changes are NOT needed in \`$DEFAULT_BRANCH\`, close this PR.

---
_This PR was automatically created by the cherry-pick workflow._
EOF
)")

echo "Created cherry-pick PR: $PR_URL"
echo "pr_url=$PR_URL" >> "$GITHUB_OUTPUT"

- name: Comment on original PR (success)
if: steps.prepare.outputs.conflict == 'false'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORIGINAL_PR: ${{ github.event.pull_request.number }}
CHERRY_BRANCH: ${{ steps.prepare.outputs.cherry_branch }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
gh pr comment "$ORIGINAL_PR" --body "$(cat <<EOF
## Cherry-pick Created

A cherry-pick PR to \`$DEFAULT_BRANCH\` has been automatically created.

**Please review and merge if this change should also be in \`$DEFAULT_BRANCH\`.**

If the cherry-pick is not needed, close the PR.
EOF
)"

- name: Create issue for conflict
id: create_issue
if: steps.prepare.outputs.conflict == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_BRANCH: ${{ github.event.pull_request.base.ref }}
ORIGINAL_PR: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
MERGE_SHA: ${{ github.event.pull_request.merge_commit_sha }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
set -euo pipefail

# Create issue without assignee (assignee may fail if user can't be assigned)
ISSUE_URL=$(gh issue create \
--title "Manual cherry-pick needed: $PR_TITLE" \
--label "cherry-pick" \
--label "conflict" \
--label "needs-attention" \
--body "$(cat <<EOF
## Manual Cherry-pick Required

The automatic cherry-pick of #$ORIGINAL_PR to \`$DEFAULT_BRANCH\` failed due to merge conflicts.

### Original PR
- **PR:** #$ORIGINAL_PR
- **Title:** $PR_TITLE
- **Author:** @$PR_AUTHOR
- **Merged to:** \`$RELEASE_BRANCH\`
- **Commit:** \`$MERGE_SHA\`

### Manual Cherry-pick Instructions

\`\`\`bash
# Checkout main branch
git checkout $DEFAULT_BRANCH
git pull origin $DEFAULT_BRANCH

# Create a new branch for the cherry-pick
git checkout -b cherry-pick-pr-$ORIGINAL_PR

# Cherry-pick the commit (use -m 1 for merge commits)
git cherry-pick $MERGE_SHA
# OR for merge commits:
# git cherry-pick -m 1 $MERGE_SHA

# Resolve conflicts manually, then:
git add .
git cherry-pick --continue

# Push and create PR
git push origin cherry-pick-pr-$ORIGINAL_PR
gh pr create --base $DEFAULT_BRANCH --title "Cherry-pick: $PR_TITLE"
\`\`\`

### Decision Required
- [ ] Cherry-pick is needed - resolve conflicts and apply
- [ ] Cherry-pick is NOT needed - close this issue

---
_This issue was automatically created by the cherry-pick workflow._
EOF
)")

echo "Created issue for manual cherry-pick: $ISSUE_URL"
echo "issue_url=$ISSUE_URL" >> "$GITHUB_OUTPUT"

- name: Attempt to assign issue
if: steps.prepare.outputs.conflict == 'true' && steps.create_issue.outputs.issue_url != ''
continue-on-error: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
ISSUE_URL: ${{ steps.create_issue.outputs.issue_url }}
run: |
# Extract issue number from URL
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
gh issue edit "$ISSUE_NUMBER" --add-assignee "$PR_AUTHOR" || echo "Could not assign to $PR_AUTHOR, skipping assignment"

- name: Comment on original PR (conflict)
if: steps.prepare.outputs.conflict == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORIGINAL_PR: ${{ github.event.pull_request.number }}
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
run: |
gh pr comment "$ORIGINAL_PR" --body "$(cat <<EOF
## Cherry-pick Conflict

Automatic cherry-pick to \`$DEFAULT_BRANCH\` failed due to merge conflicts.

An issue has been created with manual instructions. Please resolve if this change should also be in \`$DEFAULT_BRANCH\`.
EOF
)"
Loading