Skip to content

Commit 90415ce

Browse files
feat(e2e): automated Marketplace publish + auto-update, push-on-v2 trigger
Squashed e2e workflow improvements: - Re-enable automated Marketplace publish in Job 1 (publish + share + install) so ADO auto-updates the dev org and jobs 2 & 3 exercise the build under test without a manual UI upload. Gated on ADO_E2E_MARKETPLACE_PAT (unset => no-op, manual artifact still works). - Resolve the publish version against the live Marketplace version: prefer 0.<PR#>.<run_number>, else take the live version and bump its patch, satisfying Marketplace's "version must increase" rule. - Also trigger the workflow on push to v2 (PR merged into v2 or direct push) for post-merge validation. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 570250f commit 90415ce

1 file changed

Lines changed: 113 additions & 6 deletions

File tree

.github/workflows/e2e-plugin-tests.yml

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ on:
6262
# Run automatically when a PR receives the "safe to test" label.
6363
pull_request_target:
6464
types: [labeled]
65+
# Run automatically when code lands on v2 — i.e. a PR is merged into v2 or
66+
# something is pushed to it directly — so the release branch is validated
67+
# post-merge (build + publish + sanity + OIDC against the merged code).
68+
push:
69+
branches: [v2]
6570
# Allow manual triggering from the Actions UI for debugging.
6671
workflow_dispatch:
6772
inputs:
@@ -94,7 +99,8 @@ jobs:
9499
name: '1. Build .vsix'
95100
if: |
96101
contains(github.event.pull_request.labels.*.name, 'safe to test') ||
97-
github.event_name == 'workflow_dispatch'
102+
github.event_name == 'workflow_dispatch' ||
103+
github.event_name == 'push'
98104
runs-on: ubuntu-latest
99105
timeout-minutes: 20
100106

@@ -154,12 +160,60 @@ jobs:
154160
print(f"Rewrote {len(paths)} task GUIDs and names.")
155161
PYEOF
156162
163+
- name: Resolve next extension version
164+
id: version
165+
# Marketplace requires each publish of a (publisher, extension-id) to
166+
# use a version strictly greater than the currently published one, and
167+
# ADO only auto-updates to a higher version.
168+
#
169+
# Preferred (traceable) version is 0.<PR#>.<run_number>. But this e2e
170+
# extension is shared across all runs and already has older publishes
171+
# (e.g. 0.647.87), so a low PR/run can be <= what's live and get
172+
# rejected. Strategy:
173+
# • candidate = 0.<PR#>.<run_number>
174+
# • query the version currently live on Marketplace
175+
# • if candidate > live → publish candidate (keeps traceability)
176+
# • if candidate <= live → take live and bump its patch (+1)
177+
# When no Marketplace PAT is available we can't query, so we just emit
178+
# the candidate (the publish step is skipped in that case anyway).
179+
env:
180+
MARKETPLACE_PAT: ${{ secrets.ADO_E2E_MARKETPLACE_PAT }}
181+
PUBLISHER: "${{ secrets.ADO_E2E_PUBLISHER_ORG || secrets.ADO_E2E_ORG }}-private"
182+
EXTENSION_ID: "${{ secrets.ADO_E2E_EXTENSION_ID || 'jfrog-azure-devops-extension-e2etest' }}"
183+
PR_NUMBER: ${{ github.event.pull_request.number || 0 }}
184+
RUN_NUMBER: ${{ github.run_number }}
185+
run: |
186+
set -euo pipefail
187+
export CANDIDATE="0.${PR_NUMBER}.${RUN_NUMBER}"
188+
export LIVE="0.0.0"
189+
if [ -n "${MARKETPLACE_PAT:-}" ]; then
190+
TFX_OUT=$(npx --yes tfx-cli extension show --publisher "$PUBLISHER" --extension-id "$EXTENSION_ID" --token "$MARKETPLACE_PAT" 2>&1 || true)
191+
LIVE=$(echo "$TFX_OUT" | python3 -c "import sys,json; raw=sys.stdin.read(); s=raw.find('{'); d=json.loads(raw[s:]) if s>=0 else {}; v=d.get('versions',[]); print(v[0]['version'] if v else '0.0.0')" 2>/dev/null || echo '0.0.0')
192+
[ -z "$LIVE" ] && LIVE='0.0.0'
193+
export LIVE
194+
fi
195+
echo "Live version on Marketplace : $LIVE"
196+
echo "Candidate (0.PR.run) : $CANDIDATE"
197+
python3 - <<'PY' >> "$GITHUB_OUTPUT"
198+
import os
199+
def parse(v):
200+
parts = (str(v).split('.') + ['0', '0', '0'])[:3]
201+
return [int(p) if p.isdigit() else 0 for p in parts]
202+
cand = os.environ['CANDIDATE']
203+
live = os.environ['LIVE']
204+
c, l = parse(cand), parse(live)
205+
final = cand if c > l else f"{l[0]}.{l[1]}.{l[2] + 1}"
206+
print(f"vsix_version={final}")
207+
PY
208+
echo "Resolved version written to job output."
209+
157210
- name: Package .vsix
158211
id: build_vsix
159212
env:
160-
# Traceable version so we can correlate the installed extension
161-
# back to this exact PR run.
162-
VSIX_VERSION: "0.${{ github.event.pull_request.number || 0 }}.${{ github.run_number }}"
213+
# Version resolved above: preferred 0.<PR#>.<run_number>, or a
214+
# patch-bump of the live Marketplace version when that would
215+
# otherwise be <= what's already published.
216+
VSIX_VERSION: ${{ steps.version.outputs.vsix_version }}
163217
# Bake the real destination publisher into the .vsix at build time.
164218
# Marketplace rejects uploads if the manifest publisher and the
165219
# destination publisher don't match exactly, so we cannot use a
@@ -212,6 +266,59 @@ jobs:
212266
retention-days: 14
213267
if-no-files-found: error
214268

269+
- name: Publish to Marketplace, share and install (auto-update the dev org)
270+
# Fully automates what used to be the manual UI step: publish the
271+
# freshly built .vsix to the private publisher, share it with the dev
272+
# org, and ensure it is installed there. Once installed, ADO
273+
# auto-updates the org to each new version on subsequent runs, so
274+
# jobs 2 & 3 exercise THIS PR's code.
275+
#
276+
# Gated on ADO_E2E_MARKETPLACE_PAT: if the secret is absent the step
277+
# is a no-op and the manual artifact-upload flow (below) still works.
278+
# The version scheme (0.<run_number>.<run_attempt>) guarantees a
279+
# strictly increasing version, so re-runs never hit the old
280+
# "version must increase" failure.
281+
env:
282+
MARKETPLACE_PAT: ${{ secrets.ADO_E2E_MARKETPLACE_PAT }}
283+
ADO_ORG: ${{ secrets.ADO_E2E_ORG }}
284+
PUBLISHER: "${{ secrets.ADO_E2E_PUBLISHER_ORG || secrets.ADO_E2E_ORG }}-private"
285+
EXTENSION_ID: ${{ steps.build_vsix.outputs.extension_id }}
286+
VSIX_VERSION: ${{ steps.build_vsix.outputs.vsix_version }}
287+
run: |
288+
set -euo pipefail
289+
if [ -z "${MARKETPLACE_PAT:-}" ]; then
290+
echo "ADO_E2E_MARKETPLACE_PAT not set — skipping auto-publish."
291+
echo "The .vsix is available as a workflow artifact for manual upload."
292+
exit 0
293+
fi
294+
295+
vsix_path="$(ls -1 ./*.vsix | head -1)"
296+
echo "Publishing $vsix_path (version $VSIX_VERSION) to publisher '$PUBLISHER' and sharing with org '$ADO_ORG'..."
297+
npx tfx extension publish \
298+
--vsix "$vsix_path" \
299+
--token "$MARKETPLACE_PAT" \
300+
--share-with "$ADO_ORG" \
301+
--no-wait-validation
302+
echo "Published and shared."
303+
304+
# Ensure the extension is installed in the org so ADO auto-updates to
305+
# each new version. Idempotent: on subsequent runs it's already
306+
# installed, so a non-zero exit here is non-fatal.
307+
echo "Ensuring extension '$EXTENSION_ID' is installed in '$ADO_ORG'..."
308+
if npx tfx extension install \
309+
--publisher "$PUBLISHER" \
310+
--extension-id "$EXTENSION_ID" \
311+
--service-url "https://${ADO_ORG}.visualstudio.com" \
312+
--token "$MARKETPLACE_PAT"; then
313+
echo "Install/enable confirmed."
314+
else
315+
echo "Install returned non-zero (likely already installed) — continuing."
316+
fi
317+
318+
echo "Waiting 90s for Marketplace async validation to settle before jobs 2 & 3 run their version check..."
319+
sleep 90
320+
echo "Done — ADO will auto-update to version $VSIX_VERSION."
321+
215322
- name: Write install instructions to job summary
216323
env:
217324
VSIX_VERSION: ${{ steps.build_vsix.outputs.vsix_version }}
@@ -220,11 +327,11 @@ jobs:
220327
ADO_ORG: ${{ secrets.ADO_E2E_ORG }}
221328
run: |
222329
{
223-
echo "## Manual install step (≈3 min, only when testing PR code)"
330+
echo "## Install (auto by default — manual steps are a fallback)"
224331
echo ""
225332
echo "**This PR built:** \`$VSIX_NAME\` (version \`$VSIX_VERSION\`, extension id \`$EXTENSION_ID\`)"
226333
echo ""
227-
echo "If you want the ADO test pipelines (jobs 2 & 3) to actually exercise this PR's code, do the following. If you skip this step the pipelines still run, but against whatever .vsix was installed previously."
334+
echo "When the \`ADO_E2E_MARKETPLACE_PAT\` secret is set, the *Publish to Marketplace* step already published, shared and installed this build, and ADO auto-updates the dev org — so jobs 2 & 3 test this PR's code automatically. The steps below are only needed if that secret is unset or the auto-publish step was skipped/failed."
228335
echo ""
229336
echo "1. **Download the .vsix** from the *Artifacts* section at the bottom of this run page (artifact: \`jfrog-ext-vsix-${{ github.run_number }}\`). It downloads as a .zip wrapper — unzip it to get the actual .vsix."
230337
echo "2. **Upload to your publisher** at https://marketplace.visualstudio.com/manage/publishers/${ADO_ORG}-private"

0 commit comments

Comments
 (0)