4848 echo "run=${run}" >> "${GITHUB_OUTPUT}"
4949
5050 cpu-build :
51- if : github.event_name != 'pull_request_target'
51+ needs : gate
52+ if : needs.gate.outputs.run-cadence == 'true'
5253 uses : pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
5354 permissions :
5455 id-token : write
5859 runner : linux.2xlarge
5960 docker-image : ci-image:executorch-ubuntu-22.04-clang12
6061 submodules : recursive
61- ref : ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
62+ ref : ${{ ( github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }}
6263 timeout : 90
6364 upload-artifact : cadence-runner-build
6465 script : |
@@ -74,14 +75,14 @@ jobs:
7475 cp cmake-out/backends/cadence/cadence_runner "${RUNNER_ARTIFACT_DIR}/"
7576
7677 cpu-test :
77- needs : cpu-build
78- if : github.event_name != 'pull_request_target '
78+ needs : [gate, cpu-build]
79+ if : needs.gate.outputs.run-cadence == 'true '
7980 permissions :
8081 id-token : write
8182 contents : read
8283 uses : ./.github/workflows/_test_cadence.yml
8384 with :
84- ref : ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
85+ ref : ${{ ( github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }}
8586
8687 # Cross-compile cadence_executor_runner for each Cadence Xtensa core, one job
8788 # per backend so they show as separate lines (no matrix grouping). Shared logic
@@ -108,3 +109,98 @@ jobs:
108109 with :
109110 backend : vision
110111 ref : ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }}
112+
113+ # Fork exports run via pull_request_target, whose native check runs attach to
114+ # the base SHA and never surface on the PR. Mirror per-job check runs onto the
115+ # PR head SHA so each cadence job shows up as its own check on the export PR,
116+ # linking to its logs. Same-repo PRs run via pull_request and report natively.
117+ export-checks-start :
118+ needs : gate
119+ if : github.event_name == 'pull_request_target' && needs.gate.outputs.run-cadence == 'true'
120+ runs-on : ubuntu-latest
121+ permissions :
122+ checks : write
123+ outputs :
124+ ids : ${{ steps.create.outputs.ids }}
125+ steps :
126+ - id : create
127+ uses : actions/github-script@v7
128+ with :
129+ script : |
130+ const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
131+ const jobs = ['cpu-build', 'cpu-test', 'hifi-build', 'vision-build'];
132+ const ids = {};
133+ for (const job of jobs) {
134+ const res = await github.rest.checks.create({
135+ owner: context.repo.owner,
136+ repo: context.repo.repo,
137+ name: `cadence (export) / ${job}`,
138+ head_sha: context.payload.pull_request.head.sha,
139+ status: 'in_progress',
140+ details_url: runUrl,
141+ output: {
142+ title: 'Running on the export workflow run',
143+ summary: `Mirrored from the pull_request_target run (native checks attach to the base SHA). See ${runUrl}`,
144+ },
145+ });
146+ ids[job] = res.data.id;
147+ // Persist after each create so a mid-loop failure still propagates
148+ // partial IDs to the finish job (which then updates, not duplicates).
149+ core.setOutput('ids', JSON.stringify(ids));
150+ }
151+
152+ export-checks-finish :
153+ needs : [gate, cpu-build, cpu-test, hifi-build, vision-build, export-checks-start]
154+ if : always() && github.event_name == 'pull_request_target' && needs.gate.outputs.run-cadence == 'true'
155+ runs-on : ubuntu-latest
156+ permissions :
157+ checks : write
158+ actions : read
159+ steps :
160+ - uses : actions/github-script@v7
161+ env :
162+ NEEDS : ${{ toJSON(needs) }}
163+ IDS : ${{ needs.export-checks-start.outputs.ids }}
164+ with :
165+ script : |
166+ const needs = JSON.parse(process.env.NEEDS);
167+ const ids = JSON.parse(process.env.IDS || '{}');
168+ const owner = context.repo.owner;
169+ const repo = context.repo.repo;
170+ const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`;
171+ const jobs = ['cpu-build', 'cpu-test', 'hifi-build', 'vision-build'];
172+ // Link each check to its inner reusable-workflow job for a direct log
173+ // link; fall back to the run page when a job name is not matchable.
174+ const { data } = await github.rest.actions.listJobsForWorkflowRun({
175+ owner, repo, run_id: context.runId, per_page: 100,
176+ });
177+ const urlFor = (job) => {
178+ const m = data.jobs.find(j => j.name === job || j.name.startsWith(`${job} /`));
179+ return m ? m.html_url : runUrl;
180+ };
181+ // Valid check-run conclusions; anything unexpected fails closed.
182+ const allowed = ['success', 'failure', 'cancelled', 'skipped', 'timed_out'];
183+ for (const job of jobs) {
184+ const result = (needs[job] && needs[job].result) || 'unknown';
185+ const conclusion = allowed.includes(result) ? result : 'failure';
186+ const fields = {
187+ owner,
188+ repo,
189+ status: 'completed',
190+ conclusion,
191+ details_url: urlFor(job),
192+ output: {
193+ title: `${job}: ${result}`,
194+ summary: `Result mirrored from the export workflow run: ${runUrl}`,
195+ },
196+ };
197+ if (ids[job]) {
198+ await github.rest.checks.update({ ...fields, check_run_id: ids[job] });
199+ } else {
200+ await github.rest.checks.create({
201+ ...fields,
202+ name: `cadence (export) / ${job}`,
203+ head_sha: context.payload.pull_request.head.sha,
204+ });
205+ }
206+ }
0 commit comments