1+ name : " Download Build Artifacts"
2+ description : " Downloads a specific artifact from the Build workflow for the same commit SHA"
3+
4+ inputs :
5+ # In Azure we use build ID of build pipeline to retrieve Strimzi artifacts
6+ # This can be achieved here as well, but after offline discussion we agreed we will try to use just commit sha
7+ # as each commit should have only one unique passed build. In case we will find it is not sufficient
8+ # we can easily add another input runId and skip find-build job and directly download artifact.
9+ # TODO - the comment can be removed once we agree it is sufficient for releases
10+ sha :
11+ description : " Commit SHA to find build artifacts for"
12+ required : true
13+ artifactName :
14+ description : " Name of the artifact to download (e.g., 'strimzi-binaries.tar', 'containers-amd64.tar')"
15+ required : true
16+ waitForBuild :
17+ description : " Wait for build to complete if it's still running"
18+ required : false
19+ default : " true"
20+ maxWaitMinutes :
21+ description : " Maximum time to wait for build completion (in minutes)"
22+ required : false
23+ default : " 60"
24+
25+ outputs :
26+ buildRunId :
27+ description : " The ID of the build workflow run"
28+ value : ${{ steps.find-build.outputs.run_id }}
29+ buildStatus :
30+ description : " Status of the build workflow"
31+ value : ${{ steps.find-build.outputs.status }}
32+
33+ runs :
34+ using : " composite"
35+ steps :
36+ - name : Find Build Workflow Run
37+ id : find-build
38+ uses : actions/github-script@v7
39+ env :
40+ INPUT_SHA : ${{ inputs.sha }}
41+ WAIT_FOR_BUILD : ${{ inputs.waitForBuild }}
42+ MAX_WAIT_MINUTES : ${{ inputs.maxWaitMinutes }}
43+ with :
44+ script : |
45+ const {owner, repo} = context.repo;
46+ const sha = process.env.INPUT_SHA;
47+ const waitForBuild = process.env.WAIT_FOR_BUILD === 'true';
48+ const maxWaitMinutes = parseInt(process.env.MAX_WAIT_MINUTES);
49+
50+ core.info(`🔍 Looking for Build workflow run for commit: ${sha}`);
51+
52+ const maxWaitSeconds = maxWaitMinutes * 60;
53+ const startTime = Date.now();
54+
55+ // Function to find build run
56+ async function findBuildRun() {
57+ const runs = await github.rest.actions.listWorkflowRuns({
58+ owner,
59+ repo,
60+ workflow_id: 'build.yml',
61+ head_sha: sha,
62+ per_page: 1
63+ });
64+ return runs.data.workflow_runs[0];
65+ }
66+
67+ // Initial attempt to find build
68+ let buildRun = await findBuildRun();
69+
70+ if (!buildRun) {
71+ if (waitForBuild) {
72+ core.info('⏳ No build found yet. Waiting for build workflow to start...');
73+
74+ // Wait for build to appear
75+ while (!buildRun) {
76+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
77+
78+ if (elapsed >= maxWaitSeconds) {
79+ core.setFailed(`❌ Timeout: No build workflow found after waiting ${maxWaitMinutes} minutes`);
80+ core.setFailed(`Please ensure the Build workflow has been triggered for commit ${sha}`);
81+ return;
82+ }
83+
84+ core.info(`Waiting... (${elapsed}s elapsed, max: ${maxWaitSeconds}s)`);
85+ await new Promise(resolve => setTimeout(resolve, 30000)); // Sleep 30 seconds
86+ buildRun = await findBuildRun();
87+ }
88+ } else {
89+ core.setFailed(`❌ No build workflow run found for commit ${sha}`);
90+ core.setFailed('Please trigger the Build workflow first or enable waitForBuild');
91+ return;
92+ }
93+ }
94+
95+ core.info(`✅ Found Build workflow run: #${buildRun.id}`);
96+ core.info(`📊 Status: ${buildRun.status}, Conclusion: ${buildRun.conclusion}`);
97+
98+ // Wait for build to complete if it's still running
99+ if (buildRun.status !== 'completed' && waitForBuild) {
100+ core.info('⏳ Build is still running. Waiting for completion...');
101+
102+ while (buildRun.status !== 'completed') {
103+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
104+
105+ if (elapsed >= maxWaitSeconds) {
106+ core.setFailed(`❌ Timeout: Build did not complete within ${maxWaitMinutes} minutes`);
107+ core.setFailed(`Build run: ${context.serverUrl}/${owner}/${repo}/actions/runs/${buildRun.id}`);
108+ return;
109+ }
110+
111+ core.info(`Build still running... (${elapsed}s elapsed, max: ${maxWaitSeconds}s)`);
112+ await new Promise(resolve => setTimeout(resolve, 60000)); // Sleep 60 seconds
113+
114+ buildRun = await findBuildRun();
115+ }
116+
117+ core.info(`✅ Build completed with status: ${buildRun.conclusion}`);
118+ }
119+
120+ // Check if build was successful
121+ if (buildRun.status === 'completed' && buildRun.conclusion !== 'success') {
122+ core.setFailed(`❌ Build workflow failed with conclusion: ${buildRun.conclusion}`);
123+ core.setFailed(`Build run: ${context.serverUrl}/${owner}/${repo}/actions/runs/${buildRun.id}`);
124+ return;
125+ }
126+
127+ // Output results
128+ core.setOutput('run_id', buildRun.id.toString());
129+ core.setOutput('status', buildRun.status);
130+ core.setOutput('conclusion', buildRun.conclusion || '');
131+
132+ core.info(`🎯 Build workflow run #${buildRun.id} is ready for artifact download`);
133+ core.info(`Build URL: ${context.serverUrl}/${owner}/${repo}/actions/runs/${buildRun.id}`);
134+
135+ - name : Download Artifact
136+ uses : actions/download-artifact@v4
137+ with :
138+ name : ${{ inputs.artifactName }}
139+ run-id : ${{ steps.find-build.outputs.run_id }}
140+ github-token : ${{ github.token }}
0 commit comments