Skip to content

Commit 9eebcd2

Browse files
authored
Merge branch 'main' into feat/shell-exec-synchronous-endpoint
2 parents b8c6460 + 4ea68c4 commit 9eebcd2

41 files changed

Lines changed: 1122 additions & 836 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/associated-pr/action.yml

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ inputs:
1010
description: GitHub user to Slack user mapping
1111
required: false
1212
default: "{}"
13+
display-pr-details:
14+
description: Whether to display associated PR details in the step summary
15+
required: false
16+
default: "false"
17+
export-file-changes:
18+
description: |
19+
Newline-separated list of filenames to check for changes in the PR.
20+
When provided, populates the `changes` output with the subset of these files
21+
that were modified in the PR.
22+
required: false
23+
default: ""
1324

1425
outputs:
1526
number:
@@ -31,11 +42,16 @@ outputs:
3142
description: The head repository full name of the PR
3243
value: ${{ steps.associated-pr.outputs.head_repo }}
3344
labels:
34-
description: Comma-separated list of PR labels
45+
description: JSON array of PR label names (use `fromJSON(...)` in expressions)
3546
value: ${{ steps.associated-pr.outputs.labels }}
3647
closed:
3748
description: Whether the PR is closed
3849
value: ${{ steps.associated-pr.outputs.closed }}
50+
changes:
51+
description: |
52+
JSON array of filenames from `export-file-changes` that were modified in the PR.
53+
Empty array when `export-file-changes` is not provided or no PR was found.
54+
value: ${{ steps.associated-pr.outputs.changes }}
3955

4056
runs:
4157
using: "composite"
@@ -73,36 +89,44 @@ runs:
7389
env:
7490
GH_USER_TO_SLACK_USER: ${{ inputs.gh-user-to-slack-user }}
7591
INPUT_SHA: ${{ steps.get-sha.outputs.sha }}
92+
INPUT_EXPORT_FILE_CHANGES: ${{ inputs.export-file-changes }}
7693
with:
7794
script: | # js
7895
const commitSha = process.env.INPUT_SHA || context.sha;
79-
let pr = context.payload.pull_request;
80-
81-
if (!pr || pr.head?.sha !== commitSha) {
82-
const maxRetries = 5;
83-
const baseDelay = 2000;
84-
85-
// Retry logic to handle timing issues with GitHub API
86-
// Sometimes the commit-PR association isn't immediately available after merge
87-
for (let attempt = 0; attempt < maxRetries; attempt++) {
88-
if (attempt > 0) {
89-
// Exponential backoff: 2s, 4s, 8s, 16s, 32s
90-
const delay = baseDelay * Math.pow(2, attempt - 1);
91-
core.info(`PR not found, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})...`);
92-
await new Promise(resolve => setTimeout(resolve, delay));
93-
}
94-
95-
const response = await github.rest.repos.listPullRequestsAssociatedWithCommit({
96-
commit_sha: commitSha,
97-
owner: context.repo.owner,
98-
repo: context.repo.repo,
99-
});
100-
101-
if (response.data && response.data.length > 0) {
102-
pr = response.data[0];
103-
core.info(`Found PR #${pr.number} on attempt ${attempt + 1}`);
104-
break;
105-
}
96+
const filesToTrack = (process.env.INPUT_EXPORT_FILE_CHANGES || '')
97+
.split('\n')
98+
.map(s => s.trim())
99+
.filter(Boolean);
100+
core.setOutput('changes', '[]');
101+
core.setOutput('labels', '[]');
102+
103+
let pr;
104+
const maxRetries = 5;
105+
const baseDelay = 2000;
106+
107+
// Always fetch from the API rather than reading context.payload.pull_request:
108+
// the webhook payload is frozen at event-fire time and does not reflect
109+
// label/metadata changes made afterwards.
110+
// Retry logic also handles timing issues where the commit-PR association
111+
// isn't immediately available after merge.
112+
for (let attempt = 0; attempt < maxRetries; attempt++) {
113+
if (attempt > 0) {
114+
// Exponential backoff: 2s, 4s, 8s, 16s, 32s
115+
const delay = baseDelay * Math.pow(2, attempt - 1);
116+
core.info(`PR not found, retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})...`);
117+
await new Promise(resolve => setTimeout(resolve, delay));
118+
}
119+
120+
const response = await github.rest.repos.listPullRequestsAssociatedWithCommit({
121+
commit_sha: commitSha,
122+
owner: context.repo.owner,
123+
repo: context.repo.repo,
124+
});
125+
126+
if (response.data && response.data.length > 0) {
127+
pr = response.data[0];
128+
core.info(`Found PR #${pr.number} on attempt ${attempt + 1}`);
129+
break;
106130
}
107131
}
108132
@@ -124,11 +148,33 @@ runs:
124148
core.setOutput('title', pr.title);
125149
core.setOutput('head_ref', pr.head.ref);
126150
core.setOutput('head_repo', pr.head.repo?.full_name || '');
127-
core.setOutput('labels', (pr.labels || []).map(l => l.name).join(','));
151+
core.setOutput('labels', JSON.stringify((pr.labels || []).map(l => l.name)));
128152
core.setOutput('closed', pr.closed_at ? 'true' : 'false');
129153
130154
const author = pr.merged_by?.login || pr.user.login;
131155
core.setOutput('author', author);
132156
133157
const userMapping = JSON.parse(process.env.GH_USER_TO_SLACK_USER || '{}');
134158
core.setOutput('slack-user', userMapping[author] || "");
159+
160+
if (filesToTrack.length > 0) {
161+
const files = await github.paginate(github.rest.pulls.listFiles, {
162+
owner: context.repo.owner,
163+
repo: context.repo.repo,
164+
pull_number: pr.number,
165+
});
166+
const changedFilenames = new Set(files.map(f => f.filename));
167+
const changes = filesToTrack.filter(f => changedFilenames.has(f));
168+
core.setOutput('changes', JSON.stringify(changes));
169+
}
170+
171+
- name: Display associated PR details
172+
if: steps.associated-pr.outputs.number != '' && inputs.display-pr-details == 'true'
173+
env:
174+
PR_NUMBER: ${{ steps.associated-pr.outputs.number }}
175+
PR_TITLE: ${{ steps.associated-pr.outputs.title }}
176+
shell: bash
177+
run: | # shell
178+
pr_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/pull/${PR_NUMBER}"
179+
echo "### Associated PR" >> "$GITHUB_STEP_SUMMARY"
180+
echo "[#${PR_NUMBER} - ${PR_TITLE}](${pr_url})" >> "$GITHUB_STEP_SUMMARY"

.github/actions/console-web-ui-testing/action.yml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,15 @@ inputs:
3434
description: Mailsac API key for email verification
3535
required: true
3636
email-verification-strategy:
37-
description: Email verification strategy (mailsac or auth0-ticket)
37+
description: Email verification strategy (mailsac-code or auth0-ticket)
38+
required: false
39+
default: "mailsac-code"
40+
test-user-email:
41+
description: Pre-registered test user email for authenticated tests
42+
required: false
43+
test-user-password:
44+
description: Pre-registered test user password for authenticated tests
3845
required: false
39-
default: "mailsac"
4046

4147
runs:
4248
using: "composite"
@@ -63,6 +69,8 @@ runs:
6369
AUTH0_M2M_CLIENT_SECRET: ${{ inputs.auth0-m2m-client-secret }}
6470
MAILSAC_API_KEY: ${{ inputs.mailsac-api-key }}
6571
EMAIL_VERIFICATION_STRATEGY: ${{ inputs.email-verification-strategy }}
72+
TEST_USER_EMAIL: ${{ inputs.test-user-email }}
73+
TEST_USER_PASSWORD: ${{ inputs.test-user-password }}
6674
USER_DATA_DIR: ${{ runner.temp }}/chrome-profile-${{ github.run_id }}-${{ github.run_attempt }}
6775
CI: "true"
6876
shell: bash

.github/actions/poll-check-status/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ runs:
3737
MAX_RETRIES: ${{ inputs.max_retries }}
3838
EXPECTED_CONCLUSIONS: ${{ inputs.expected_conclusions }}
3939
with:
40-
script: |
40+
script: | # js
4141
const checkName = process.env.CHECK_NAME;
4242
const sha = process.env.CHECK_SHA;
4343
const checkType = process.env.CHECK_TYPE;

0 commit comments

Comments
 (0)