Skip to content

Commit ae02dde

Browse files
authored
Merge pull request #179 from salesforcecli/ms/caller-call-ci-status-check
refactor: move gate-check to consuming repos
2 parents 669732e + 7bee937 commit ae02dde

2 files changed

Lines changed: 128 additions & 156 deletions

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Find Nightly Candidate
2+
3+
# Reusable workflow to find eligible nightly tag for promotion
4+
# Used by repos to implement their own gate-check before calling vscode-promote-prerelease.yml
5+
6+
on:
7+
workflow_call:
8+
inputs:
9+
min-tag-age-days:
10+
description: "Minimum nightly age in days before eligible for promotion"
11+
required: false
12+
default: "7"
13+
type: string
14+
release-tag:
15+
description: "Specific release tag to use (overrides min-tag-age-days)"
16+
required: false
17+
type: string
18+
outputs:
19+
commit-sha:
20+
description: "Commit SHA that the nightly tag points to"
21+
value: ${{ jobs.find-nightly.outputs.commit-sha }}
22+
nightly-tag:
23+
description: "Nightly tag selected for promotion"
24+
value: ${{ jobs.find-nightly.outputs.nightly-tag }}
25+
26+
jobs:
27+
find-nightly:
28+
runs-on: ubuntu-latest
29+
outputs:
30+
commit-sha: ${{ steps.find.outputs.commit-sha }}
31+
nightly-tag: ${{ steps.find.outputs.nightly-tag }}
32+
steps:
33+
# Checks out the calling repository (not salesforcecli/github-workflows)
34+
# Note: May need explicit token parameter if calling from private repos
35+
- name: Checkout
36+
uses: actions/checkout@v6
37+
with:
38+
fetch-depth: 0
39+
40+
- name: Find eligible nightly
41+
id: find
42+
env:
43+
RELEASE_TAG: ${{ inputs.release-tag || '' }}
44+
MIN_TAG_AGE_DAYS: ${{ inputs.min-tag-age-days || '7' }}
45+
run: |
46+
# If specific release-tag provided, use it directly
47+
if [ -n "$RELEASE_TAG" ]; then
48+
echo "Using specific release tag: $RELEASE_TAG"
49+
50+
if ! git rev-parse "$RELEASE_TAG" >/dev/null 2>&1; then
51+
echo "❌ Release tag $RELEASE_TAG does not exist"
52+
exit 1
53+
fi
54+
55+
COMMIT_SHA=$(git rev-parse "$RELEASE_TAG^{commit}")
56+
echo "nightly-tag=$RELEASE_TAG" >> $GITHUB_OUTPUT
57+
echo "commit-sha=$COMMIT_SHA" >> $GITHUB_OUTPUT
58+
echo "✅ Found release tag: $RELEASE_TAG (commit: $COMMIT_SHA)"
59+
exit 0
60+
fi
61+
62+
# Auto-detect mode: find nightly tags older than MIN_TAG_AGE_DAYS
63+
echo "Finding nightly tags older than $MIN_TAG_AGE_DAYS days..."
64+
65+
NIGHTLY_TAGS=$(git tag -l '*-nightly.*' --sort=-creatordate)
66+
67+
if [ -z "$NIGHTLY_TAGS" ]; then
68+
echo "❌ No nightly tags found"
69+
exit 1
70+
fi
71+
72+
CUTOFF_TIMESTAMP=$(date -u -d "$MIN_TAG_AGE_DAYS days ago" +%s 2>/dev/null || date -u -v-${MIN_TAG_AGE_DAYS}d +%s)
73+
74+
while IFS= read -r tag; do
75+
[ -z "$tag" ] && continue
76+
77+
TAG_TIMESTAMP=$(git log -1 --format=%ct "$tag" 2>/dev/null)
78+
[ -z "$TAG_TIMESTAMP" ] && continue
79+
80+
if [ "$TAG_TIMESTAMP" -lt "$CUTOFF_TIMESTAMP" ]; then
81+
VERSION=$(echo "$tag" | grep -oP '\d+\.\d+\.\d+' | head -1)
82+
PROMO_TAG="marketplace-prerelease-*-v${VERSION}"
83+
84+
if ! git tag -l "$PROMO_TAG" | grep -q .; then
85+
SELECTED_TAG="$tag"
86+
SELECTED_SHA=$(git rev-list -n 1 "$tag")
87+
echo "nightly-tag=$SELECTED_TAG" >> $GITHUB_OUTPUT
88+
echo "commit-sha=$SELECTED_SHA" >> $GITHUB_OUTPUT
89+
echo "✅ Found eligible nightly: $SELECTED_TAG (SHA: $SELECTED_SHA)"
90+
exit 0
91+
fi
92+
fi
93+
done <<< "$NIGHTLY_TAGS"
94+
95+
echo "❌ No eligible nightly found (all nightlies either too new or already promoted)"
96+
exit 1

.github/workflows/vscode-promote-prerelease.yml

Lines changed: 32 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,51 @@
11
name: 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

4043
on:
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')"
@@ -63,11 +61,6 @@ on:
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
@@ -81,13 +74,8 @@ on:
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')"
@@ -106,11 +94,6 @@ on:
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

137120
jobs:
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

Comments
 (0)