@@ -60,21 +60,18 @@ jobs:
6060 private-key : ${{ secrets.OCMBOT_PRIV_KEY }}
6161
6262 - name : Checkout Repository
63- # Checkout repository for tagging
6463 uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
6564 with :
6665 sparse-checkout : ${{ env.COMPONENT_PATH }}
6766 ref : ${{ github.event.inputs.branch }}
6867 token : ${{ steps.get_token.outputs.token }}
6968
7069 - name : Setup git config
71- # Set committer for git identity
7270 run : |
7371 git config --global user.name "${{ github.actor }}"
7472 git config --global user.email "${{ github.actor }}@users.noreply.github.com"
7573
76- - name : Create ${{ needs.prepare.outputs.new_tag }}
77- # Create and push tag if not existing
74+ - name : Create tag
7875 id : tag
7976 uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
8077 env :
@@ -116,8 +113,7 @@ jobs:
116113 permissions :
117114 contents : write
118115 steps :
119- - name : Decode changelog to file
120- # Recreate changelog file from base64 string for release body
116+ - name : Decode changelog
121117 env :
122118 CHANGELOG_B64 : ${{ needs.prepare.outputs.changelog_b64 }}
123119 run : echo "$CHANGELOG_B64" | base64 --decode > "${{ runner.temp }}/CHANGELOG.md"
@@ -235,32 +231,15 @@ jobs:
235231 permissions :
236232 contents : write
237233 packages : write
238- outputs :
239- set_latest : ${{ steps.promote_oci.outputs.set_latest }}
240234 steps :
241- - name : Validate release preconditions
242- env :
243- RC_TAG : ${{ needs.prepare.outputs.new_tag }}
244- PROMOTION_TAG : ${{ needs.prepare.outputs.promotion_tag }}
245- run : |
246- if [ -z "$RC_TAG" ]; then
247- echo "::error::Missing RC tag from prepare step"
248- exit 1
249- fi
250- if [ -z "$PROMOTION_TAG" ]; then
251- echo "::error::Missing promotion tag"
252- exit 1
253- fi
254- echo "✅ RC: $RC_TAG → Final: $PROMOTION_TAG"
255-
256235 - name : Generate App Token
257236 id : get_token
258237 uses : actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
259238 with :
260239 app-id : ${{ secrets.OCMBOT_APP_ID }}
261240 private-key : ${{ secrets.OCMBOT_PRIV_KEY }}
262241
263- - name : Checkout Repository
242+ - name : Checkout
264243 uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
265244 with :
266245 sparse-checkout : ${{ env.COMPONENT_PATH }}
@@ -273,7 +252,8 @@ jobs:
273252 git config --global user.name "${{ github.actor }}"
274253 git config --global user.email "${{ github.actor }}@users.noreply.github.com"
275254
276- - name : Create final tag from RC commit
255+ - name : Create final tag
256+ # Points final tag to same commit as RC tag (no rebuild needed)
277257 uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
278258 env :
279259 RC_TAG : ${{ needs.prepare.outputs.new_tag }}
@@ -282,29 +262,16 @@ jobs:
282262 github-token : ${{ steps.get_token.outputs.token }}
283263 script : |
284264 const { execFileSync } = require("child_process");
285- const rcTag = process.env.RC_TAG;
286- const finalTag = process.env.FINAL_TAG;
287-
288- if (!rcTag || !finalTag) {
289- core.setFailed("Missing RC_TAG or FINAL_TAG");
290- return;
291- }
292-
293- try {
294- execFileSync("git", ["rev-parse", `refs/tags/${finalTag}`], { stdio: "pipe" });
295- core.setFailed(`Final tag ${finalTag} already exists. Refusing to overwrite immutable tag.`);
296- return;
265+ const { RC_TAG: rcTag, FINAL_TAG: finalTag } = process.env;
266+ try {
267+ execFileSync("git", ["rev-parse", `refs/tags/${finalTag}`], { stdio: "pipe" });
268+ core.setFailed(`Tag ${finalTag} already exists`);
269+ return;
297270 } catch {}
298-
299271 const rcSha = execFileSync("git", ["rev-parse", `refs/tags/${rcTag}^{commit}`], { stdio: "pipe" }).toString().trim();
300- if (!rcSha) {
301- core.setFailed(`Could not resolve commit for RC tag ${rcTag}`);
302- return;
303- }
304-
305272 execFileSync("git", ["tag", "-a", finalTag, rcSha, "-m", `Promote ${rcTag} to ${finalTag}`]);
306273 execFileSync("git", ["push", "origin", `refs/tags/${finalTag}`]);
307- core.info(`✅ Created final tag ${finalTag} from ${rcTag} at ${rcSha} `);
274+ core.info(`✅ Created final tag ${finalTag} from ${rcTag} ( ${rcSha.substring(0,7)}) `);
308275
309276 - name : Setup ORAS
310277 uses : oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1
@@ -317,52 +284,19 @@ jobs:
317284 password : ${{ secrets.GITHUB_TOKEN }}
318285
319286 - name : Promote OCI image tags
320- id : promote_oci
321- uses : actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
322287 env :
323288 RC_VERSION : ${{ needs.prepare.outputs.new_version }}
324289 FINAL_VERSION : ${{ needs.prepare.outputs.promotion_version }}
325290 TARGET_REPO : ${{ env.REGISTRY }}/${{ github.repository_owner }}/cli
326- with :
327- script : |
328- const { execFileSync } = require('child_process');
329- const { RC_VERSION: rc, FINAL_VERSION: final, TARGET_REPO: repo } = process.env;
330-
331- if (!rc || !final) { core.setFailed('Missing RC_VERSION or FINAL_VERSION'); return; }
332-
333- // Get highest existing final version from GitHub releases (not OCI)
334- let highest = '';
335- try {
336- const releases = await github.rest.repos.listReleases({
337- owner: context.repo.owner,
338- repo: context.repo.repo,
339- per_page: 100,
340- });
341- highest = releases.data
342- .filter(r => !r.prerelease && r.tag_name.startsWith('cli/v'))
343- .map(r => r.tag_name.replace('cli/v', ''))
344- .filter(t => /^\d+\.\d+\.\d+$/.test(t))
345- .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))
346- .pop() || '';
347- } catch (e) { core.warning(`Could not fetch existing releases: ${e.message}`); }
348-
349- // Set :latest only if this version is >= the current highest
350- const setLatest = !highest || final.localeCompare(highest, undefined, { numeric: true }) >= 0;
351- const tagArgs = setLatest ? [final, "latest"] : [final];
352-
353- execFileSync("oras", ["tag", `${repo}:${rc}`, ...tagArgs], { stdio: 'inherit' });
354- core.info(setLatest ? `✅ Tagged :${final} and :latest` : `⚠️ Tagged :${final} (${highest} is higher)`);
355-
356- // Export setLatest for use in release_final job
357- core.setOutput('set_latest', setLatest ? 'true' : 'false');
358-
359- await core.summary.addHeading('OCI Image Promotion').addTable([
360- [{data: 'Field', header: true}, {data: 'Value', header: true}],
361- ['Source', `${repo}:${rc}`],
362- ['Final', `${repo}:${final}`],
363- ['Highest existing', highest || '(none)'],
364- ['Latest', setLatest ? 'Yes' : `No (${highest} > ${final})`],
365- ]).write();
291+ SET_LATEST : ${{ needs.prepare.outputs.set_latest }}
292+ run : |
293+ if [ "$SET_LATEST" = "true" ]; then
294+ oras tag "${TARGET_REPO}:${RC_VERSION}" "${FINAL_VERSION}" "latest"
295+ echo "✅ Tagged :${FINAL_VERSION} and :latest"
296+ else
297+ oras tag "${TARGET_REPO}:${RC_VERSION}" "${FINAL_VERSION}"
298+ echo "⚠️ Tagged :${FINAL_VERSION} (not setting :latest)"
299+ fi
366300
367301 # --------------------------------------------------------
368302 # 7. RELEASE FINAL: Create GitHub final release
@@ -405,7 +339,8 @@ jobs:
405339 TARGET_REPO : ${{ env.REGISTRY }}/${{ github.repository_owner }}/cli
406340 BINARIES_DIR : ${{ runner.temp }}/binaries
407341 NOTES_FILE : ${{ runner.temp }}/CHANGELOG.md
408- SET_LATEST : ${{ needs.promote_final.outputs.set_latest }}
342+ SET_LATEST : ${{ needs.prepare.outputs.set_latest }}
343+ HIGHEST_FINAL_VERSION : ${{ needs.prepare.outputs.highest_final_version }}
409344 with :
410345 github-token : ${{ secrets.GITHUB_TOKEN }}
411346 script : |
@@ -467,6 +402,7 @@ jobs:
467402 }
468403
469404 const releaseUrl = created.data.html_url;
405+ const highestFinal = process.env.HIGHEST_FINAL_VERSION || '(none)';
470406 const ociTags = setLatest
471407 ? `${targetRepo}:${finalVersion}, ${targetRepo}:latest`
472408 : `${targetRepo}:${finalVersion}`;
@@ -477,6 +413,7 @@ jobs:
477413 [{data: 'Field', header: true}, {data: 'Value', header: true}],
478414 ['Final Tag', finalTag],
479415 ['Promoted from RC', rcTag],
416+ ['Highest Final Version', highestFinal],
480417 ['OCI Tags', ociTags],
481418 ['GitHub Latest', setLatest ? 'Yes' : 'No (older version)'],
482419 ])
0 commit comments