11name : Promote Nightly to Pre-release
22
3- # Promotes a vetted nightly build to pre-release on VS Code Marketplace and Open VSX.
3+ # Publishes a nightly build to pre-release on VS Code Marketplace and Open VSX.
44#
5- # Two modes:
6- # 1. Auto-detect (default): finds oldest unpromoted nightly ≥ min-tag-age-days
7- # 2. Specific tag: publishes a specific release tag (for emergency pre-releases)
5+ # NOTE: Callers should use vscode-find-nightly-candidate.yml and check-ci-status action
6+ # BEFORE calling this workflow to implement their own gate-check logic.
87#
9- # Usage - Auto-detect mode :
8+ # Usage:
109# jobs:
11- # promote :
12- # uses: salesforcecli/github-workflows/.github/workflows/vscode-promote-prerelease .yml@main
10+ # find-nightly :
11+ # uses: salesforcecli/github-workflows/.github/workflows/vscode-find-nightly-candidate .yml@main
1312# with:
14- # extension-name: 'apex-lsp-vscode-extension'
1513# min-tag-age-days: '7'
16- # vsix-name-pattern: 'apex-language-server-extension-*.vsix' # optional, default: *.vsix
17- # exclude-web-vsix: 'true' # optional, default: false
18- # required-ci-checks: '["CI Complete"]'
19- # dry-run: 'false'
20- # secrets: inherit
2114#
22- # Usage - Specific tag mode (emergency pre-releases):
23- # jobs:
15+ # gate-check:
16+ # needs: find-nightly
17+ # runs-on: ubuntu-latest
18+ # steps:
19+ # - uses: salesforcecli/github-workflows/.github/actions/vscode/check-ci-status@main
20+ # with:
21+ # commit-sha: ${{ needs.find-nightly.outputs.commit-sha }}
22+ # token: ${{ secrets.GITHUB_TOKEN }}
23+ # required-checks: '["CI Complete"]'
24+ #
2425# promote:
26+ # needs: [find-nightly, gate-check]
2527# uses: salesforcecli/github-workflows/.github/workflows/vscode-promote-prerelease.yml@main
2628# with:
27- # release-tag: 'v67.13.7 -nightly.develop.20260820' # specific tag to publish
29+ # release-tag: ${{ needs.find -nightly.outputs.nightly- tag }}
2830# extension-name: 'apex-lsp-vscode-extension'
31+ # vsix-name-pattern: 'apex-language-server-extension-*.vsix'
32+ # exclude-web-vsix: 'true'
33+ # dry-run: 'false'
2934# secrets: inherit
3035#
3136# Requirements - calling repository must have:
3237# - Nightly tags matching *-nightly.* (e.g., v1.2.3-nightly.20260629)
3338# - GitHub releases for each nightly tag with VSIX file(s) attached
34- # - Passing CI checks on nightly commits
3539# - Secrets: IDEE_GH_TOKEN, VSCE_PERSONAL_ACCESS_TOKEN, IDEE_OVSX_PAT
3640#
37- # Workflow: finds eligible nightly (or uses release-tag) → verifies CI →
38- # downloads VSIX → publishes to both marketplaces → creates tracking tag
41+ # Workflow: downloads VSIX → publishes to both marketplaces → creates tracking tag
3942
4043on :
4144 workflow_call :
4245 inputs :
4346 release-tag :
44- description : " Specific release tag to publish (e.g., v67.13.7-nightly.develop.20260820). Overrides min-tag-age-days auto-detection."
45- required : false
46- type : string
47- min-tag-age-days :
48- description : " Minimum nightly age in days before eligible for promotion (ignored if release-tag provided)"
49- required : false
50- default : " 7"
47+ description : " Nightly tag to publish (e.g., v67.13.7-nightly.develop.20260820). Callers should use vscode-find-nightly-candidate.yml to find this."
48+ required : true
5149 type : string
5250 extension-name :
5351 description : " Extension name for tracking tag (e.g., 'apex-lsp-vscode-extension')"
6361 required : false
6462 default : " false"
6563 type : string
66- required-ci-checks :
67- description : " JSON array of CI check names required before promotion"
68- required : false
69- default : ' ["CI Complete"]'
70- type : string
7164 dry-run :
7265 description : " Run in dry-run mode (no actual publishing or tagging)"
7366 required : false
8174 workflow_dispatch :
8275 inputs :
8376 release-tag :
84- description : " Specific release tag to publish (e.g., v67.13.7-nightly.develop.20260820). Overrides min-tag-age-days auto-detection."
85- required : false
86- type : string
87- min-tag-age-days :
88- description : " Minimum nightly age in days before eligible for promotion (default: 7, ignored if release-tag provided)"
89- required : false
90- default : " 7"
77+ description : " Nightly tag to publish (e.g., v67.13.7-nightly.develop.20260820)"
78+ required : true
9179 type : string
9280 extension-name :
9381 description : " Extension name for tracking tag (e.g., 'apex-lsp-vscode-extension')"
10694 options :
10795 - " false"
10896 - " true"
109- required-ci-checks :
110- description : " JSON array of CI check names required before promotion"
111- required : false
112- default : ' ["CI Complete"]'
113- type : string
11497 dry-run :
11598 description : " Run in dry-run mode (no actual publishing or tagging)"
11699 required : false
@@ -135,116 +118,7 @@ permissions:
135118 actions : read
136119
137120jobs :
138- find-nightly-candidate :
139- runs-on : ubuntu-latest
140- outputs :
141- commit-sha : ${{ steps.find.outputs.commit-sha }}
142- nightly-tag : ${{ steps.find.outputs.nightly-tag }}
143- steps :
144- - name : Checkout
145- uses : actions/checkout@v6
146- with :
147- fetch-depth : 0
148- token : ${{ secrets.IDEE_GH_TOKEN }}
149-
150- - name : Find eligible nightly
151- id : find
152- env :
153- RELEASE_TAG : ${{ inputs.release-tag || '' }}
154- MIN_TAG_AGE_DAYS : ${{ inputs.min-tag-age-days || '7' }}
155- run : |
156- # If specific release-tag provided, use it directly
157- if [ -n "$RELEASE_TAG" ]; then
158- echo "Using specific release tag: $RELEASE_TAG"
159-
160- # Verify tag exists
161- if ! git rev-parse "$RELEASE_TAG" >/dev/null 2>&1; then
162- echo "::error::Release tag $RELEASE_TAG does not exist"
163- exit 1
164- fi
165-
166- COMMIT_SHA=$(git rev-parse "$RELEASE_TAG^{commit}")
167- echo "nightly-tag=$RELEASE_TAG" >> $GITHUB_OUTPUT
168- echo "commit-sha=$COMMIT_SHA" >> $GITHUB_OUTPUT
169- echo "✓ Found release tag: $RELEASE_TAG (commit: $COMMIT_SHA)"
170- exit 0
171- fi
172-
173- # Auto-detect mode: find nightly tags older than MIN_TAG_AGE_DAYS
174- echo "Finding nightly tags older than $MIN_TAG_AGE_DAYS days..."
175-
176- # Get all nightly tags sorted by date (newest first)
177- NIGHTLY_TAGS=$(git tag -l '*-nightly.*' --sort=-creatordate)
178-
179- if [ -z "$NIGHTLY_TAGS" ]; then
180- echo "No nightly tags found"
181- echo "nightly-tag=" >> $GITHUB_OUTPUT
182- echo "commit-sha=" >> $GITHUB_OUTPUT
183- exit 0
184- fi
185-
186- # Calculate cutoff timestamp (MIN_TAG_AGE_DAYS ago)
187- CUTOFF_TIMESTAMP=$(date -u -d "$MIN_TAG_AGE_DAYS days ago" +%s 2>/dev/null || date -u -v-${MIN_TAG_AGE_DAYS}d +%s)
188-
189- # Find first tag older than cutoff that hasn't been promoted
190- SELECTED_TAG=""
191- SELECTED_SHA=""
192-
193- while IFS= read -r tag; do
194- [ -z "$tag" ] && continue
195-
196- # Get tag creation timestamp
197- TAG_TIMESTAMP=$(git log -1 --format=%ct "$tag" 2>/dev/null)
198- [ -z "$TAG_TIMESTAMP" ] && continue
199-
200- # Check if tag is old enough
201- if [ "$TAG_TIMESTAMP" -lt "$CUTOFF_TIMESTAMP" ]; then
202- # Check if already promoted (has corresponding marketplace-prerelease tag)
203- VERSION=$(echo "$tag" | grep -oP '\d+\.\d+\.\d+' | head -1)
204- PROMO_TAG="marketplace-prerelease-*-v${VERSION}"
205-
206- if ! git tag -l "$PROMO_TAG" | grep -q .; then
207- SELECTED_TAG="$tag"
208- SELECTED_SHA=$(git rev-list -n 1 "$tag")
209- break
210- fi
211- fi
212- done <<< "$NIGHTLY_TAGS"
213-
214- if [ -n "$SELECTED_TAG" ]; then
215- echo "Found eligible nightly: $SELECTED_TAG (SHA: $SELECTED_SHA)"
216- echo "nightly-tag=$SELECTED_TAG" >> $GITHUB_OUTPUT
217- echo "commit-sha=$SELECTED_SHA" >> $GITHUB_OUTPUT
218- else
219- echo "No eligible nightly found"
220- echo "nightly-tag=" >> $GITHUB_OUTPUT
221- echo "commit-sha=" >> $GITHUB_OUTPUT
222- fi
223-
224- - name : Fail if no candidate found
225- if : steps.find.outputs.nightly-tag == ''
226- run : |
227- echo "No eligible nightly candidate found. Nothing to promote this week."
228- exit 1
229-
230- quality-gate :
231- needs : find-nightly-candidate
232- runs-on : ubuntu-latest
233- steps :
234- - name : Checkout
235- uses : actions/checkout@v6
236-
237- - name : Check CI status for candidate commit
238- uses : salesforcecli/github-workflows/.github/actions/vscode/check-ci-status@main
239- with :
240- commit-sha : ${{ needs.find-nightly-candidate.outputs.commit-sha }}
241- token : ${{ secrets.IDEE_GH_TOKEN }}
242- # `CI Complete` is the aggregate release gate emitted by vscode-ci-template.
243- # Callers can override it for their repository's release-worthy checks.
244- required-checks : ${{ inputs.required-ci-checks }}
245-
246121 publish :
247- needs : [find-nightly-candidate, quality-gate]
248122 runs-on : ubuntu-latest
249123 strategy :
250124 matrix :
@@ -267,7 +141,7 @@ jobs:
267141 - name : Download VSIX from nightly GitHub release
268142 env :
269143 GH_TOKEN : ${{ secrets.IDEE_GH_TOKEN }}
270- NIGHTLY_TAG : ${{ needs.find-nightly-candidate.outputs.nightly -tag }}
144+ NIGHTLY_TAG : ${{ inputs.release -tag }}
271145 VSIX_PATTERN : ${{ inputs.vsix-name-pattern || '*.vsix' }}
272146 EXCLUDE_WEB : ${{ inputs.exclude-web-vsix || 'false' }}
273147 run : |
@@ -304,7 +178,7 @@ jobs:
304178 OVSX_PAT : ${{ secrets.IDEE_OVSX_PAT }}
305179
306180 tag-promoted :
307- needs : [find-nightly-candidate, publish]
181+ needs : publish
308182 runs-on : ubuntu-latest
309183 steps :
310184 - name : Checkout
@@ -315,7 +189,7 @@ jobs:
315189
316190 - name : Create marketplace-prerelease tracking tag
317191 env :
318- NIGHTLY_TAG : ${{ needs.find-nightly-candidate.outputs.nightly -tag }}
192+ NIGHTLY_TAG : ${{ inputs.release -tag }}
319193 EXTENSION_NAME : ${{ inputs.extension-name }}
320194 DRY_RUN : ${{ inputs.dry-run || 'false' }}
321195 GH_TOKEN : ${{ secrets.IDEE_GH_TOKEN }}
@@ -327,8 +201,10 @@ jobs:
327201 exit 1
328202 fi
329203
204+ # Get commit SHA from the tag
205+ COMMIT_SHA=$(git rev-list -n 1 "$NIGHTLY_TAG")
206+
330207 TRACKING_TAG="marketplace-prerelease-${EXTENSION_NAME}-v${VERSION}"
331- COMMIT_SHA="${{ needs.find-nightly-candidate.outputs.commit-sha }}"
332208
333209 echo "Creating tracking tag: $TRACKING_TAG → $COMMIT_SHA"
334210
0 commit comments