Skip to content

Commit 201eecf

Browse files
authored
ci: create PR in emulator repo to build preview emulator binaries (#147)
1 parent 3850837 commit 201eecf

2 files changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
name: Create Emulator PR
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
types: [opened, synchronize, closed]
7+
8+
permissions:
9+
contents: read
10+
pull-requests: write
11+
issues: write
12+
13+
jobs:
14+
cleanup-emulator-pr:
15+
if: github.event.action == 'closed'
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: webfactory/ssh-agent@v0.9.1
19+
with:
20+
ssh-private-key: ${{ secrets.EMULATOR_KEY }}
21+
22+
- name: Delete emulator branch
23+
run: |
24+
PR_NUMBER="${{ github.event.pull_request.number }}"
25+
EMULATOR_BRANCH="testing-sdk-pr-${PR_NUMBER}-sync"
26+
27+
git clone git@github.com:aws/aws-durable-execution-emulator.git
28+
cd aws-durable-execution-emulator
29+
git push origin --delete "$EMULATOR_BRANCH" || echo "Branch may not exist"
30+
31+
create-emulator-pr:
32+
if: github.event.action == 'opened' || github.event.action == 'synchronize'
33+
runs-on: ubuntu-latest
34+
steps:
35+
- name: Checkout testing SDK repo
36+
uses: actions/checkout@v5
37+
with:
38+
path: testing-sdk
39+
40+
- name: Set up Python
41+
uses: actions/setup-python@v6
42+
with:
43+
python-version: "3.13"
44+
45+
- name: Install uv
46+
uses: astral-sh/setup-uv@v4
47+
48+
- uses: webfactory/ssh-agent@v0.9.1
49+
with:
50+
ssh-private-key: |
51+
${{ secrets.EMULATOR_PRIVATE_KEY }}
52+
${{ secrets.SDK_KEY }}
53+
54+
- name: Checkout emulator repo
55+
run: |
56+
git clone git@github.com:aws/aws-durable-execution-emulator.git emulator
57+
58+
- name: Create branch and update uv.lock
59+
working-directory: emulator
60+
run: |
61+
# Configure git
62+
git config user.name "github-actions[bot]"
63+
git config user.email "github-actions[bot]@users.noreply.github.com"
64+
65+
# Get PR info
66+
BRANCH_NAME="${{ github.event.pull_request.head.ref }}"
67+
PR_NUMBER="${{ github.event.pull_request.number }}"
68+
EMULATOR_BRANCH="testing-sdk-pr-${PR_NUMBER}-sync"
69+
70+
# Create or update branch
71+
git fetch origin
72+
if git show-ref --verify --quiet refs/remotes/origin/"$EMULATOR_BRANCH"; then
73+
git checkout "$EMULATOR_BRANCH"
74+
git reset --hard origin/main
75+
else
76+
git checkout -b "$EMULATOR_BRANCH"
77+
fi
78+
79+
# Update pyproject.toml to use local testing SDK (temporary, not committed)
80+
TESTING_SDK_PATH="$(realpath ../testing-sdk)"
81+
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
82+
rm pyproject.toml.bak
83+
84+
# Generate new uv.lock with the specific testing SDK commit
85+
uv lock
86+
87+
# Show what changed
88+
echo "=== Changes to be committed ==="
89+
git diff --name-status
90+
git diff uv.lock || echo "uv.lock is a new file"
91+
92+
# Restore original pyproject.toml (don't commit the temporary change)
93+
git checkout pyproject.toml
94+
95+
# Commit and push only the uv.lock file
96+
git add uv.lock
97+
if git commit -m "Lock testing SDK branch: $BRANCH_NAME (PR #$PR_NUMBER)"; then
98+
echo "Changes committed successfully"
99+
git push --force-with-lease origin "$EMULATOR_BRANCH"
100+
echo "Branch pushed successfully"
101+
else
102+
echo "No changes to commit"
103+
# Still need to push the branch even if no changes
104+
git push --force-with-lease origin "$EMULATOR_BRANCH" || git push origin "$EMULATOR_BRANCH"
105+
fi
106+
107+
- name: Create or update PR in emulator repo
108+
uses: actions/github-script@v7
109+
with:
110+
github-token: ${{ secrets.EMULATOR_REPO_TOKEN }}
111+
script: |
112+
const fs = require('fs');
113+
const pr = context.payload.pull_request;
114+
const branch_name = pr.head.ref;
115+
const emulator_branch = `testing-sdk-pr-${pr.number}-sync`;
116+
117+
// Wait a moment for branch to be available
118+
await new Promise(resolve => setTimeout(resolve, 2000));
119+
120+
// Read and populate PR template
121+
const template = fs.readFileSync('testing-sdk/.github/workflows/emulator-pr-template.md', 'utf8');
122+
const pr_body = template
123+
.replace(/{{PR_NUMBER}}/g, pr.number)
124+
.replace(/{{BRANCH_NAME}}/g, branch_name);
125+
126+
try {
127+
// Check if PR already exists
128+
let existingPR = null;
129+
try {
130+
const prs = await github.rest.pulls.list({
131+
owner: 'aws',
132+
repo: 'aws-durable-execution-emulator',
133+
head: `aws:${emulator_branch}`,
134+
state: 'open'
135+
});
136+
existingPR = prs.data[0];
137+
} catch (e) {
138+
console.log('No existing PR found');
139+
}
140+
141+
if (existingPR) {
142+
// Update existing PR
143+
await github.rest.pulls.update({
144+
owner: 'aws',
145+
repo: 'aws-durable-execution-emulator',
146+
pull_number: existingPR.number,
147+
title: `Lock testing SDK branch: ${branch_name} (PR #${pr.number})`,
148+
body: pr_body
149+
});
150+
151+
console.log(`Updated emulator PR: ${existingPR.html_url}`);
152+
153+
// Comment on original PR about update
154+
await github.rest.issues.createComment({
155+
owner: context.repo.owner,
156+
repo: context.repo.repo,
157+
issue_number: pr.number,
158+
body: `🔄 **Emulator PR Updated**\n\nThe emulator PR has been updated with locked dependencies:\n\n➡️ ${existingPR.html_url}`
159+
});
160+
} else {
161+
// Create new PR
162+
console.log("Creating an emulator PR")
163+
const response = await github.rest.pulls.create({
164+
owner: 'aws',
165+
repo: 'aws-durable-execution-emulator',
166+
title: `Lock testing SDK branch: ${branch_name} (PR #${pr.number})`,
167+
head: emulator_branch,
168+
base: 'main',
169+
body: pr_body,
170+
draft: true
171+
});
172+
173+
console.log(`Created emulator PR: ${response.data.html_url}`);
174+
175+
// Comment on original PR
176+
await github.rest.issues.createComment({
177+
owner: context.repo.owner,
178+
repo: context.repo.repo,
179+
issue_number: pr.number,
180+
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.`
181+
});
182+
}
183+
184+
} catch (error) {
185+
console.log(`Error managing PR: ${error.message}`);
186+
console.log(`Error status: ${error.status}`);
187+
console.log(`Error response: ${JSON.stringify(error.response?.data)}`);
188+
core.setFailed(`Failed to manage emulator PR: ${error.message}`);
189+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
*Issue #, if available:* Related to aws/aws-durable-execution-sdk-python-testing#{{PR_NUMBER}}
2+
3+
*Description of changes:* Testing changes from testing SDK branch `{{BRANCH_NAME}}` using locked dependencies in uv.lock
4+
5+
## Dependencies
6+
This PR locks the testing SDK to a specific commit from branch `{{BRANCH_NAME}}` using uv.lock for reproducible builds.
7+
8+
PYTHON_LANGUAGE_SDK_BRANCH: main
9+
PYTHON_TESTING_SDK_BRANCH: {{BRANCH_NAME}}
10+
11+
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

0 commit comments

Comments
 (0)