Skip to content

Commit bc4e46b

Browse files
authored
Add linux_job_v3 workflow for OSDC runners (#8129)
Add .github/workflows/linux_job_v3.yml, an OSDC (ARC) variant of linux_job_v2.yml that takes the same inputs but runs the job inside a job-level container on an ARC runner and executes the script directly, mirroring the OSDC code path in pytorch's _linux-build / _linux-test. Also add .github/workflows/test_linux_job_v3.yml exercising the new workflow on mt- ARC runners (CPU x86/arm64, A100 GPU, artifact/docs upload, and binary-matrix cases). --------- Signed-off-by: Huy Do <huydhn@gmail.com>
1 parent 90efa7e commit bc4e46b

2 files changed

Lines changed: 500 additions & 0 deletions

File tree

.github/workflows/linux_job_v3.yml

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
name: Build / Test on Linux v3 (OSDC)
2+
3+
# Same inputs as linux_job_v2.yml, but compatible with OSDC (ARC) runners.
4+
on:
5+
workflow_call:
6+
inputs:
7+
script:
8+
description: 'Script to utilize'
9+
default: "python setup.py bdist_wheel"
10+
type: string
11+
timeout:
12+
description: 'Timeout for the job (in minutes)'
13+
default: 30
14+
type: number
15+
runner:
16+
description: 'ARC runner label to utilize (e.g. mt-l-x86iavx512-8-64)'
17+
default: "mt-l-x86iavx512-8-64"
18+
type: string
19+
upload-artifact:
20+
description: |
21+
Name to give artifacts uploaded from ${RUNNER_ARTIFACT_DIR}, all the wheel files
22+
under dist/ and any files under artifacts-to-be-uploaded/ will be uploaded
23+
default: ''
24+
type: string
25+
upload-artifact-to-s3:
26+
description: |
27+
Upload the artifact to S3 instead of GitHub. This is used for large artifacts like
28+
exported model
29+
required: false
30+
default: false
31+
type: boolean
32+
download-artifact:
33+
description: 'Name to download artifacts to ${RUNNER_ARTIFACT_DIR}'
34+
default: ''
35+
type: string
36+
repository:
37+
description: 'Repository to checkout, defaults to ""'
38+
default: ""
39+
type: string
40+
fetch-depth:
41+
description: 'Number of commits to fetch, defaults to 1 similar to actions/checkout'
42+
default: 1
43+
type: number
44+
single-branch:
45+
description: 'Whether to fetch only a single branch, defaults to true'
46+
default: true
47+
type: boolean
48+
additional-fetch-refs:
49+
description: 'Additional refs to fetch, space separated'
50+
default: |
51+
refs/heads/main
52+
type: string
53+
checkout-mode:
54+
description: 'Mode of checkout; one of "normal", "blobless", "treeless".'
55+
default: "normal"
56+
type: string
57+
submodules:
58+
description:
59+
Same as actions/checkout, set to `true` to checkout submodules or `recursive` to
60+
recursively checkout everything
61+
default: ""
62+
type: string
63+
ref:
64+
description: 'Reference to checkout, defaults to "nightly"'
65+
default: ""
66+
type: string
67+
test-infra-repository:
68+
description: "Test infra repository to use"
69+
default: "pytorch/test-infra"
70+
type: string
71+
test-infra-ref:
72+
description: "Test infra reference to use"
73+
default: ""
74+
type: string
75+
use-custom-docker-registry:
76+
description: "[Ignored on OSDC] Kept for compatibility with linux_job_v2.yml."
77+
default: true
78+
type: boolean
79+
docker-image:
80+
description: |
81+
Fully-qualified, already-built Docker image to run the job inside, e.g.
82+
ghcr.io/pytorch/test-infra:cpu-x86_64-<hash> or an ECR path. The image is pulled
83+
by the runner before any step runs.
84+
default: "pytorch/almalinux-builder"
85+
type: string
86+
gpu-arch-type:
87+
description: "GPU arch type to use"
88+
default: "cpu"
89+
type: string
90+
gpu-arch-version:
91+
description: "GPU arch version to use"
92+
default: ""
93+
type: string
94+
job-name:
95+
description: "Name for the job, which is displayed in the GitHub UI"
96+
default: "linux-job"
97+
type: string
98+
continue-on-error:
99+
description: "Prevents a job from failing when a step fails. Set to true to allow a job to pass when exec script step fails."
100+
default: false
101+
type: boolean
102+
binary-matrix:
103+
description: "If we are calling this workflow with binary build matrix entry, will initialize matrix entries and env vars"
104+
required: false
105+
default: ''
106+
type: string
107+
secrets-env:
108+
description: "List of secrets to be exported to environment variables"
109+
type: string
110+
default: ''
111+
112+
jobs:
113+
job:
114+
strategy:
115+
fail-fast: false
116+
name: ${{ inputs.job-name }}
117+
permissions:
118+
id-token: write
119+
contents: read
120+
env:
121+
REPOSITORY: ${{ inputs.repository || github.repository }}
122+
# Will be blank outside of this
123+
PR_NUMBER: ${{ github.event.pull_request.number }}
124+
SCRIPT: ${{ inputs.script }}
125+
filter: ${{ inputs.checkout-mode == 'blobless' && 'blob:none' || inputs.checkout-mode == 'treeless' && 'tree:0' || null }}
126+
runs-on: ${{ inputs.runner }}
127+
# On OSDC the job runs inside this pre-built container; cuda exposes the GPUs.
128+
container:
129+
image: >-
130+
${{ inputs.docker-image == 'pytorch/almalinux-builder' && format('pytorch/almalinux-builder:{0}{1}',
131+
inputs.gpu-arch-type,
132+
inputs.gpu-arch-version)
133+
|| inputs.docker-image }}
134+
options: ${{ inputs.gpu-arch-type == 'cuda' && '--gpus all' || '' }}
135+
timeout-minutes: ${{ inputs.timeout }}
136+
steps:
137+
- name: Clean workspace
138+
run: |
139+
set -euxo pipefail
140+
echo "::group::Cleanup debug output"
141+
rm -rfv "${GITHUB_WORKSPACE}"
142+
mkdir -p "${GITHUB_WORKSPACE}"
143+
echo "::endgroup::"
144+
145+
- name: Checkout repository (${{ inputs.test-infra-repository }}@${{ inputs.test-infra-ref }})
146+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
147+
with:
148+
# Support the use case where we need to checkout someone's fork
149+
repository: ${{ inputs.test-infra-repository }}
150+
ref: ${{ inputs.test-infra-ref }}
151+
path: test-infra
152+
153+
# PyTorch, the primary target for this job template, heavily
154+
# relies on submodules. Clone them by default to avoid
155+
# surprises.
156+
submodules: 'recursive'
157+
158+
- name: Configure AWS credentials
159+
id: aws-creds
160+
continue-on-error: true
161+
uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # v1.7.0
162+
with:
163+
role-to-assume: arn:aws:iam::308535385114:role/arc
164+
aws-region: us-east-1
165+
# The max duration enforced by the server side
166+
role-duration-seconds: 18000
167+
168+
- name: Setup environment variables
169+
shell: bash
170+
run: |
171+
set -euo pipefail
172+
for name in ARTIFACT:artifacts TEST_RESULTS:test-results DOCS:docs; do
173+
var="RUNNER_${name%%:*}_DIR"
174+
dir="${RUNNER_TEMP}/${name##*:}"
175+
rm -rf "${dir}"
176+
mkdir -p "${dir}"
177+
echo "${var}=${dir}" >> "${GITHUB_ENV}"
178+
done
179+
180+
- name: Checkout repository (${{ inputs.repository || github.repository }}@${{ inputs.ref }})
181+
uses: pytorch/test-infra/.github/actions/checkout@main
182+
with:
183+
# Support the use case where we need to checkout someone's fork
184+
repository: ${{ inputs.repository || github.repository }}
185+
ref: ${{ inputs.ref || github.ref }}
186+
single-branch: ${{ inputs.single-branch }}
187+
additional-fetch-refs: ${{ inputs.additional-fetch-refs }}
188+
path: ${{ inputs.repository || github.repository }}
189+
fetch-depth: ${{ inputs.fetch-depth }}
190+
submodules: ${{ inputs.submodules }}
191+
filter: ${{ env.filter }}
192+
submodules-filter: ${{ env.filter }}
193+
194+
- name: Download artifacts (if any)
195+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
196+
if: ${{ inputs.download-artifact != '' }}
197+
with:
198+
name: ${{ inputs.download-artifact }}
199+
path: ${{ runner.temp }}/artifacts/
200+
201+
- name: Export matrix variables (if any)
202+
uses: pytorch/test-infra/.github/actions/export-matrix-variables@main
203+
if: ${{ inputs.binary-matrix != '' }}
204+
with:
205+
binary-matrix: ${{ inputs.binary-matrix }}
206+
target-os: "linux"
207+
208+
- name: Run script
209+
continue-on-error: ${{ inputs.continue-on-error }}
210+
working-directory: ${{ inputs.repository || github.repository }}
211+
env:
212+
ALL_SECRETS: ${{ toJSON(secrets) }}
213+
run: |
214+
set -ex
215+
{
216+
echo "#!/usr/bin/env bash";
217+
echo "set -eou pipefail";
218+
# shellcheck disable=SC2016
219+
echo 'eval "$(conda shell.bash hook)"';
220+
echo "set -x";
221+
echo "${SCRIPT}";
222+
} > "${RUNNER_TEMP}/exec_script"
223+
chmod +x "${RUNNER_TEMP}/exec_script"
224+
# Use $GITHUB_WORKSPACE (remapped to the container mount, e.g. /__w/...)
225+
# rather than the github.workspace expression, which returns the host path.
226+
python3 -u "${GITHUB_WORKSPACE}/test-infra/.github/scripts/run_with_env_secrets.py" "${{ inputs.secrets-env }}"
227+
228+
- name: Surface failing tests
229+
if: always()
230+
uses: pmeier/pytest-results-action@a2c1430e2bddadbad9f49a6f9b879f062c6b19b1 # v0.3.0
231+
with:
232+
path: ${{ env.RUNNER_TEST_RESULTS_DIR }}
233+
fail-on-empty: false
234+
235+
- name: Prepare artifacts for upload
236+
if: always()
237+
working-directory: ${{ inputs.repository || github.repository }}
238+
id: check-artifacts
239+
env:
240+
UPLOAD_ARTIFACT_NAME: ${{ inputs.upload-artifact }}
241+
run: |
242+
# Only do these steps if we actually want to upload an artifact
243+
if [[ -n "${UPLOAD_ARTIFACT_NAME}" ]]; then
244+
# If the default execution path is followed then we should get a wheel in the dist/ folder
245+
# attempt to just grab whatever is in there and scoop it all up
246+
if find "dist/" -name "*.whl" >/dev/null 2>/dev/null; then
247+
mv -v dist/*.whl "${RUNNER_ARTIFACT_DIR}/"
248+
fi
249+
if [[ -d "artifacts-to-be-uploaded" ]]; then
250+
mv -v artifacts-to-be-uploaded/* "${RUNNER_ARTIFACT_DIR}/"
251+
fi
252+
if [[ -d "${RUNNER_TEMP}/artifacts-to-be-uploaded" ]]; then
253+
mv -v "${RUNNER_TEMP}"/artifacts-to-be-uploaded/* "${RUNNER_ARTIFACT_DIR}/"
254+
fi
255+
fi
256+
257+
upload_docs=0
258+
# Check if there are files in the documentation folder to upload, note that
259+
# empty folders do not count
260+
if find "${RUNNER_DOCS_DIR}" -mindepth 1 -maxdepth 1 -type f | read -r; then
261+
upload_docs=1
262+
fi
263+
echo "upload-docs=${upload_docs}" >> "${GITHUB_OUTPUT}"
264+
265+
- name: Upload artifacts to GitHub (if any)
266+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
267+
if: ${{ always() && inputs.upload-artifact != '' && !inputs.upload-artifact-to-s3 }}
268+
with:
269+
name: ${{ inputs.upload-artifact }}
270+
path: ${{ runner.temp }}/artifacts/
271+
272+
- name: Upload artifacts to S3 (if any)
273+
uses: pytorch/test-infra/.github/actions/upload-artifact-s3@main
274+
if: ${{ always() && inputs.upload-artifact != '' && inputs.upload-artifact-to-s3 }}
275+
with:
276+
retention-days: 14
277+
s3-bucket: gha-artifacts
278+
s3-prefix: |
279+
${{ env.REPOSITORY }}/${{ github.run_id }}/artifacts
280+
path: ${{ runner.temp }}/artifacts/
281+
282+
- name: Upload documentation to S3 (if any)
283+
uses: pytorch/test-infra/.github/actions/upload-artifact-s3@main
284+
if: ${{ steps.check-artifacts.outputs.upload-docs == 1 && github.event.pull_request.number != '' }}
285+
with:
286+
retention-days: 14
287+
s3-bucket: doc-previews
288+
if-no-files-found: error
289+
path: ${{ env.RUNNER_DOCS_DIR }}
290+
# ${{ env.REPOSITORY }} is $OWNER/$REPO
291+
s3-prefix: ${{ env.REPOSITORY }}/${{ github.event.pull_request.number }}
292+
# Overwrite doc previews for the same PR
293+
overwrite: true

0 commit comments

Comments
 (0)