Skip to content
Merged
189 changes: 189 additions & 0 deletions .github/workflows/create-emulator-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
name: Create Emulator PR

on:
pull_request:
branches: [ main ]
types: [opened, synchronize, closed]

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

jobs:
cleanup-emulator-pr:
if: github.event.action == 'closed'
runs-on: ubuntu-latest
steps:
- uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.EMULATOR_KEY }}

- name: Delete emulator branch
run: |
PR_NUMBER="${{ github.event.pull_request.number }}"
EMULATOR_BRANCH="testing-sdk-pr-${PR_NUMBER}-sync"

git clone git@github.com:aws/aws-durable-execution-emulator.git
cd aws-durable-execution-emulator
git push origin --delete "$EMULATOR_BRANCH" || echo "Branch may not exist"

create-emulator-pr:
if: github.event.action == 'opened' || github.event.action == 'synchronize'
runs-on: ubuntu-latest
steps:
- name: Checkout testing SDK repo
uses: actions/checkout@v5
with:
path: testing-sdk

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"

- name: Install uv
uses: astral-sh/setup-uv@v4

- uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: |
${{ secrets.EMULATOR_PRIVATE_KEY }}
${{ secrets.SDK_KEY }}

- name: Checkout emulator repo
run: |
git clone git@github.com:aws/aws-durable-execution-emulator.git emulator

- name: Create branch and update uv.lock
working-directory: emulator
run: |
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

# Get PR info
BRANCH_NAME="${{ github.event.pull_request.head.ref }}"
PR_NUMBER="${{ github.event.pull_request.number }}"
EMULATOR_BRANCH="testing-sdk-pr-${PR_NUMBER}-sync"

# Create or update branch
git fetch origin
if git show-ref --verify --quiet refs/remotes/origin/"$EMULATOR_BRANCH"; then
git checkout "$EMULATOR_BRANCH"
git reset --hard origin/main
else
git checkout -b "$EMULATOR_BRANCH"
fi

# Update pyproject.toml to use local testing SDK (temporary, not committed)
TESTING_SDK_PATH="$(realpath ../testing-sdk)"
sed -i.bak "s|aws-durable-execution-sdk-python-testing @ git+ssh://git@github.com/aws/aws-durable-execution-sdk-python-testing.git|aws-durable-execution-sdk-python-testing @ file://${TESTING_SDK_PATH}|" pyproject.toml
rm pyproject.toml.bak

# Generate new uv.lock with the specific testing SDK commit
uv lock

# Show what changed
echo "=== Changes to be committed ==="
git diff --name-status
git diff uv.lock || echo "uv.lock is a new file"

# Restore original pyproject.toml (don't commit the temporary change)
git checkout pyproject.toml

# Commit and push only the uv.lock file
git add uv.lock
if git commit -m "Lock testing SDK branch: $BRANCH_NAME (PR #$PR_NUMBER)"; then
echo "Changes committed successfully"
git push --force-with-lease origin "$EMULATOR_BRANCH"
echo "Branch pushed successfully"
else
echo "No changes to commit"
# Still need to push the branch even if no changes
git push --force-with-lease origin "$EMULATOR_BRANCH" || git push origin "$EMULATOR_BRANCH"
fi

- name: Create or update PR in emulator repo
uses: actions/github-script@v7
with:
github-token: ${{ secrets.EMULATOR_REPO_TOKEN }}
script: |
const fs = require('fs');
const pr = context.payload.pull_request;
const branch_name = pr.head.ref;
const emulator_branch = `testing-sdk-pr-${pr.number}-sync`;

// Wait a moment for branch to be available
await new Promise(resolve => setTimeout(resolve, 2000));

// Read and populate PR template
const template = fs.readFileSync('testing-sdk/.github/workflows/emulator-pr-template.md', 'utf8');
const pr_body = template
.replace(/{{PR_NUMBER}}/g, pr.number)
.replace(/{{BRANCH_NAME}}/g, branch_name);

try {
// Check if PR already exists
let existingPR = null;
try {
const prs = await github.rest.pulls.list({
owner: 'aws',
repo: 'aws-durable-execution-emulator',
head: `aws:${emulator_branch}`,
state: 'open'
});
existingPR = prs.data[0];
} catch (e) {
console.log('No existing PR found');
}

if (existingPR) {
// Update existing PR
await github.rest.pulls.update({
owner: 'aws',
repo: 'aws-durable-execution-emulator',
pull_number: existingPR.number,
title: `Lock testing SDK branch: ${branch_name} (PR #${pr.number})`,
body: pr_body
});

console.log(`Updated emulator PR: ${existingPR.html_url}`);

// Comment on original PR about update
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: `🔄 **Emulator PR Updated**\n\nThe emulator PR has been updated with locked dependencies:\n\n➡️ ${existingPR.html_url}`
});
} else {
// Create new PR
console.log("Creating an emulator PR")
const response = await github.rest.pulls.create({
owner: 'aws',
repo: 'aws-durable-execution-emulator',
title: `Lock testing SDK branch: ${branch_name} (PR #${pr.number})`,
head: emulator_branch,
base: 'main',
body: pr_body,
draft: true
});

console.log(`Created emulator PR: ${response.data.html_url}`);

// Comment on original PR
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pr.number,
body: `🤖 **Emulator PR Created**\n\nA draft PR has been created with locked dependencies:\n\n➡️ ${response.data.html_url}\n\nThe emulator will build binaries using the exact testing SDK commit locked in uv.lock.`
});
}

} catch (error) {
console.log(`Error managing PR: ${error.message}`);
console.log(`Error status: ${error.status}`);
console.log(`Error response: ${JSON.stringify(error.response?.data)}`);
core.setFailed(`Failed to manage emulator PR: ${error.message}`);
}
11 changes: 11 additions & 0 deletions .github/workflows/emulator-pr-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*Issue #, if available:* Related to aws/aws-durable-execution-sdk-python-testing#{{PR_NUMBER}}

*Description of changes:* Testing changes from testing SDK branch `{{BRANCH_NAME}}` using locked dependencies in uv.lock

## Dependencies
This PR locks the testing SDK to a specific commit from branch `{{BRANCH_NAME}}` using uv.lock for reproducible builds.

PYTHON_LANGUAGE_SDK_BRANCH: main
PYTHON_TESTING_SDK_BRANCH: {{BRANCH_NAME}}

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Loading