From 6bd5dad132910c2bb735dbb6ec7fbec2c6438d52 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 15:35:18 +0300 Subject: [PATCH 01/33] Added Verdaccio venv flow, curl auth, local test script - Explicit Verdaccio config with npmjs proxy and uplink token - Selective lerna publish without force-publish - scripts/test-verdaccio-flow.sh and README for local validation Made-with: Cursor --- .github/workflows/start-venv.yaml | 127 ++++++++++++++++++++++++ scripts/README-verdaccio-test.md | 37 +++++++ scripts/test-verdaccio-flow.sh | 160 ++++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+) create mode 100644 scripts/README-verdaccio-test.md create mode 100755 scripts/test-verdaccio-flow.sh diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 3def95a..f968abf 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -46,6 +46,16 @@ on: required: false description: 'Set to true in order to trigger slack notification' default: true + useVerdaccio: + type: boolean + required: false + description: 'Build Docker with custom @frontegg packages from a template-and-libs branch via local Verdaccio' + default: false + templateAndLibsBranch: + type: string + required: false + description: 'Branch of frontegg/template-and-libs to build and publish to local Verdaccio (only used when useVerdaccio is true)' + default: '' secrets: GH_REPOSITORY_ADMIN_TOKEN: description: 'Github repository admin token' @@ -164,8 +174,110 @@ jobs: with: username: ${{ secrets.DOCKER_HUB_ACTION_USER }} password: ${{ secrets.DOCKER_HUB_ACTION_PASSWORD }} + - name: Write Verdaccio config + if: ${{ inputs.useVerdaccio }} + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: | + mkdir -p /tmp/verdaccio + cat > /tmp/verdaccio/config.yaml <> "$GITHUB_ENV" + - name: Publish changed packages to Verdaccio + if: ${{ inputs.useVerdaccio }} + working-directory: _shadow-libs + run: | + git config user.email "shadow@frontegg.com" + git config user.name "shadow-agent" + + CHANGED=$(npx lerna changed --json 2>/dev/null || echo "[]") + echo "Changed packages: ${CHANGED}" + + if [ "$CHANGED" = "[]" ]; then + echo "No packages changed — Verdaccio will proxy everything from npmjs" + exit 0 + fi + + echo "//localhost:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc + + npx lerna version prerelease \ + --no-push \ + --no-git-tag-version \ + --preid "venv.${{ github.run_number }}" \ + --yes + + npx lerna publish from-git \ + --registry http://localhost:4873 \ + --no-verify-access \ + --yes + - name: Clean up shadow libs from build context + if: ${{ inputs.useVerdaccio }} + run: rm -rf _shadow-libs - name: Check Docker Image id: check-image + if: ${{ !inputs.useVerdaccio }} run: | if docker manifest inspect ${{fromJSON(steps.params.outputs.result).venvImage}} > /dev/null 2>&1; then echo "Docker image exists, no need to build the image" @@ -177,6 +289,10 @@ jobs: - name: Generate npmrc run: | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc + if [ "${{ inputs.useVerdaccio }}" = "true" ]; then + echo '@frontegg:registry=http://localhost:4873' >> .npmrc + echo '//localhost:4873/:_authToken=fake-token' >> .npmrc + fi - name: Build and push uses: docker/build-push-action@v6 if: ${{ steps.check-image.outputs.image-exist == 'false' }} @@ -187,6 +303,17 @@ jobs: build-args: | COMMIT_HASH=${{fromJSON(steps.params.outputs.result).shortSha}} NPM_TOKEN=${{ secrets.NPM_TOKEN }} + - name: Build and push (Verdaccio) + uses: docker/build-push-action@v6 + if: ${{ inputs.useVerdaccio }} + with: + context: . + push: true + network: host + tags: ${{fromJSON(steps.params.outputs.result).image}},${{fromJSON(steps.params.outputs.result).venvImage}} + build-args: | + COMMIT_HASH=${{fromJSON(steps.params.outputs.result).shortSha}} + NPM_TOKEN=${{ secrets.NPM_TOKEN }} check-build-docker-results: if: ${{ always() }} diff --git a/scripts/README-verdaccio-test.md b/scripts/README-verdaccio-test.md new file mode 100644 index 0000000..fc80bcc --- /dev/null +++ b/scripts/README-verdaccio-test.md @@ -0,0 +1,37 @@ +# Local Verdaccio flow test + +Runs the same Verdaccio config, user registration, clone, build, and selective `lerna publish` flow as [`.github/workflows/start-venv.yaml`](../.github/workflows/start-venv.yaml) (when `useVerdaccio` is true). + +## Prerequisites + +- Docker +- Node.js / npm (for `curl` JSON parsing and `npx lerna`) +- `NPM_TOKEN` with access to private `@frontegg/*` on npmjs (for `yarn install` in template-and-libs and for Verdaccio uplink auth in the generated config) +- `GH_TOKEN` with read access to `frontegg/template-and-libs` + +## Run + +```bash +cd /path/to/workflows +export NPM_TOKEN='...' +export GH_TOKEN='...' # or: export GH_TOKEN="$(gh auth token)" +export TEMPLATE_LIBS_BRANCH='master' # or your PR branch + +# Optional: verify npmjs proxy for a specific package through Verdaccio +export PROXY_CHECK_PACKAGE='@frontegg/some-package' + +# Optional: only run through lerna changed, skip version/publish +# export SKIP_PUBLISH=1 + +bash scripts/test-verdaccio-flow.sh +``` + +## What it checks + +- Verdaccio starts with the explicit `config.yaml` (scoped `@frontegg/*` + `proxy: npmjs`, uplink bearer token). +- User registration via the npm registry HTTP API (non-interactive). +- Clone + `yarn install` + `yarn build:no-cache` on template-and-libs. +- `lerna changed` / publish only when there are changes (no `--force-publish`). +- Optional: `npm view $PROXY_CHECK_PACKAGE --registry http://localhost:4873` exercises the proxy path. + +The temp workdir is removed on exit unless you set `KEEP_WORKDIR=1` for debugging. diff --git a/scripts/test-verdaccio-flow.sh b/scripts/test-verdaccio-flow.sh new file mode 100755 index 0000000..623ba1a --- /dev/null +++ b/scripts/test-verdaccio-flow.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +# Local smoke test for the Verdaccio + selective publish flow used in start-venv.yaml. +# Mirrors: .github/workflows/start-venv.yaml (Write Verdaccio config through Publish changed packages) +# +# Required env: +# NPM_TOKEN npm token for uplink proxy to registry.npmjs.org +# GH_TOKEN GitHub PAT with repo read for frontegg/template-and-libs +# TEMPLATE_LIBS_BRANCH branch or ref to clone (e.g. master or your PR branch) +# +# Optional: +# PROXY_CHECK_PACKAGE @frontegg package name to verify npmjs proxy (default: skip if unset) +# SKIP_PUBLISH if set to "1", stop after lerna changed (no version/publish) +# WORKDIR temp root (default: mktemp) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +if [[ -z "${NPM_TOKEN:-}" ]]; then + echo "ERROR: NPM_TOKEN is required" + exit 1 +fi +if [[ -z "${GH_TOKEN:-}" ]]; then + echo "ERROR: GH_TOKEN is required (read access to frontegg/template-and-libs)" + exit 1 +fi +if [[ -z "${TEMPLATE_LIBS_BRANCH:-}" ]]; then + echo "ERROR: TEMPLATE_LIBS_BRANCH is required" + exit 1 +fi + +if ! command -v docker &>/dev/null; then + echo "ERROR: docker is required" + exit 1 +fi + +WORKDIR="${WORKDIR:-$(mktemp -d -t verdaccio-test-XXXXXX)}" +CONFIG_DIR="${WORKDIR}/verdaccio" +SHADOW_LIBS="${WORKDIR}/_shadow-libs" +RUN_ID="${RUN_ID:-$(date +%s)}" + +cleanup() { + docker rm -f verdaccio-test 2>/dev/null || true + if [[ "${KEEP_WORKDIR:-}" != "1" ]]; then + rm -rf "${WORKDIR}" + fi +} +trap cleanup EXIT + +mkdir -p "${CONFIG_DIR}" + +write_verdaccio_config() { + cat > "${CONFIG_DIR}/config.yaml" < Workdir: ${WORKDIR}" +write_verdaccio_config +echo "==> Starting Verdaccio (matches CI config shape)" +docker rm -f verdaccio-test 2>/dev/null || true +docker run -d --name verdaccio-test -p 4873:4873 \ + -v "${CONFIG_DIR}/config.yaml:/verdaccio/conf/config.yaml" \ + verdaccio/verdaccio + +for i in $(seq 1 40); do + if curl -sf http://localhost:4873/-/ping >/dev/null; then + break + fi + if [[ "${i}" -eq 40 ]]; then + echo "ERROR: Verdaccio did not become ready" + exit 1 + fi + sleep 1 +done +echo "==> Verdaccio is up" + +echo "==> Registering Verdaccio user (npm registry API, non-interactive)" +REG_BODY="$(curl -sf -X PUT "http://localhost:4873/-/user/org.couchdb.user:shadow" \ + -H "Content-Type: application/json" \ + -d '{"name":"shadow","password":"shadow","email":"shadow@frontegg.com","type":"user"}')" +VERDACCIO_NPM_TOKEN="$(echo "${REG_BODY}" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).token")" +export VERDACCIO_NPM_TOKEN +echo "==> Verdaccio npm token acquired for publish" + +echo "==> Cloning template-and-libs @ ${TEMPLATE_LIBS_BRANCH}" +rm -rf "${SHADOW_LIBS}" +git clone --depth 1 -b "${TEMPLATE_LIBS_BRANCH}" \ + "https://x-access-token:${GH_TOKEN}@github.com/frontegg/template-and-libs.git" \ + "${SHADOW_LIBS}" + +cd "${SHADOW_LIBS}" +export YARN_NPM_AUTH_TOKEN="${NPM_TOKEN}" + +echo "==> yarn install" +yarn install --immutable || YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install + +echo "==> yarn build:no-cache" +yarn build:no-cache + +git config user.email "shadow@frontegg.com" +git config user.name "shadow-agent" + +echo "==> lerna changed (json)" +CHANGED_JSON="$(npx lerna changed --json 2>/dev/null || echo "[]")" +echo "${CHANGED_JSON}" + +if [[ "${CHANGED_JSON}" = "[]" ]]; then + echo "==> No changed packages — CI would skip publish; Verdaccio proxies all @frontegg/* from npmjs" +else + if [[ "${SKIP_PUBLISH:-}" = "1" ]]; then + echo "==> SKIP_PUBLISH=1 — stopping before version/publish" + exit 0 + fi + echo "//localhost:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> "${SHADOW_LIBS}/.npmrc" + + echo "==> lerna version + publish (no --force-publish)" + npx lerna version prerelease \ + --no-push \ + --no-git-tag-version \ + --preid "local.${RUN_ID}" \ + --yes + + npx lerna publish from-git \ + --registry http://localhost:4873 \ + --no-verify-access \ + --yes +fi + +echo "==> Smoke: registry responds" +curl -sf "http://localhost:4873/-/ping" | head -c 200 || true +echo + +if [[ -n "${PROXY_CHECK_PACKAGE:-}" ]]; then + echo "==> Proxy check: npm view ${PROXY_CHECK_PACKAGE} via Verdaccio" + npm view "${PROXY_CHECK_PACKAGE}" version --registry http://localhost:4873 +fi + +echo "==> OK — Verdaccio config, clone, build, and publish/proxy path succeeded" +echo " Repo root reference: ${REPO_ROOT}" From dbdc9ab575b6c0a4634ce5f5c7ab548fbfdff61b Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 15:56:53 +0300 Subject: [PATCH 02/33] Fixed lerna EUNCOMMIT by committing post-build state before version Made-with: Cursor --- .github/workflows/start-venv.yaml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index f968abf..7cfea64 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -238,6 +238,16 @@ jobs: if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs run: yarn build:no-cache + - name: Commit post-build state + if: ${{ inputs.useVerdaccio }} + working-directory: _shadow-libs + run: | + git config user.email "shadow@frontegg.com" + git config user.name "shadow-agent" + git add -A + if ! git diff --cached --exit-code; then + git commit -m "chore: post-build" + fi - name: Register Verdaccio user and token if: ${{ inputs.useVerdaccio }} run: | @@ -249,9 +259,6 @@ jobs: if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs run: | - git config user.email "shadow@frontegg.com" - git config user.name "shadow-agent" - CHANGED=$(npx lerna changed --json 2>/dev/null || echo "[]") echo "Changed packages: ${CHANGED}" From 01b3e616c334d982e05d65d60290ce9948714504 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 16:09:31 +0300 Subject: [PATCH 03/33] Fixed review issues: shallow clone, health check, duplicate lerna, publish strategy - fetch-depth: 0 for template-and-libs so lerna has version tags - Explicit Verdaccio health check failure after retry loop - Single `lerna changed` call, result passed via GITHUB_OUTPUT - Dropped `--no-git-tag-version`, switched to `from-package` so publish works without git tags - Build + register + publish steps skipped when no packages changed Made-with: Cursor --- .github/workflows/start-venv.yaml | 50 ++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 7cfea64..8fb51db 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -212,6 +212,7 @@ jobs: for i in $(seq 1 30); do curl -sf http://localhost:4873/-/ping && break || sleep 1 done + curl -sf http://localhost:4873/-/ping || { echo "ERROR: Verdaccio did not start"; exit 1; } - name: Enable Corepack if: ${{ inputs.useVerdaccio }} run: corepack enable @@ -228,17 +229,14 @@ jobs: ref: ${{ inputs.templateAndLibsBranch }} path: _shadow-libs token: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} + fetch-depth: 0 - name: Install library dependencies if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs run: yarn install --immutable || YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install env: YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - name: Build all library packages - if: ${{ inputs.useVerdaccio }} - working-directory: _shadow-libs - run: yarn build:no-cache - - name: Commit post-build state + - name: Commit post-install state if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs run: | @@ -246,36 +244,52 @@ jobs: git config user.name "shadow-agent" git add -A if ! git diff --cached --exit-code; then - git commit -m "chore: post-build" + git commit -m "chore: post-install" fi - - name: Register Verdaccio user and token + - name: Detect changed packages if: ${{ inputs.useVerdaccio }} + id: lerna-changed + working-directory: _shadow-libs + run: | + CHANGED_JSON=$(npx lerna changed --json 2>/dev/null || echo "[]") + echo "Changed packages: ${CHANGED_JSON}" + + if [ "${CHANGED_JSON}" = "[]" ]; then + echo "has_changes=false" >> "$GITHUB_OUTPUT" + else + echo "has_changes=true" >> "$GITHUB_OUTPUT" + + SCOPES=$(echo "${CHANGED_JSON}" | node -e " + const pkgs = JSON.parse(require('fs').readFileSync(0,'utf8')); + process.stdout.write(pkgs.map(p => '--scope ' + p.name).join(' ')); + ") + echo "scopes=${SCOPES}" >> "$GITHUB_OUTPUT" + fi + - name: Build changed packages and their dependencies + if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} + working-directory: _shadow-libs + run: | + echo "Building: ${{ steps.lerna-changed.outputs.scopes }}" + npx lerna run build --no-cache ${{ steps.lerna-changed.outputs.scopes }} --include-dependencies + - name: Register Verdaccio user and token + if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} run: | REG_BODY="$(curl -sf -X PUT "http://localhost:4873/-/user/org.couchdb.user:shadow" \ -H "Content-Type: application/json" \ -d '{"name":"shadow","password":"shadow","email":"shadow@frontegg.com","type":"user"}')" echo "VERDACCIO_NPM_TOKEN=$(echo "${REG_BODY}" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).token")" >> "$GITHUB_ENV" - name: Publish changed packages to Verdaccio - if: ${{ inputs.useVerdaccio }} + if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} working-directory: _shadow-libs run: | - CHANGED=$(npx lerna changed --json 2>/dev/null || echo "[]") - echo "Changed packages: ${CHANGED}" - - if [ "$CHANGED" = "[]" ]; then - echo "No packages changed — Verdaccio will proxy everything from npmjs" - exit 0 - fi - echo "//localhost:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc npx lerna version prerelease \ --no-push \ - --no-git-tag-version \ --preid "venv.${{ github.run_number }}" \ --yes - npx lerna publish from-git \ + npx lerna publish from-package \ --registry http://localhost:4873 \ --no-verify-access \ --yes From 47c143722eb7951091fc4f71dcff2be97bca20b6 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 16:16:24 +0300 Subject: [PATCH 04/33] Improved lerna changed to use --since origin/master instead of full history Made-with: Cursor --- .github/workflows/start-venv.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 8fb51db..62a95e8 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -229,7 +229,10 @@ jobs: ref: ${{ inputs.templateAndLibsBranch }} path: _shadow-libs token: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} - fetch-depth: 0 + - name: Fetch master ref for lerna comparison + if: ${{ inputs.useVerdaccio }} + working-directory: _shadow-libs + run: git fetch origin master --depth=1 - name: Install library dependencies if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs @@ -251,7 +254,7 @@ jobs: id: lerna-changed working-directory: _shadow-libs run: | - CHANGED_JSON=$(npx lerna changed --json 2>/dev/null || echo "[]") + CHANGED_JSON=$(npx lerna changed --since origin/master --json 2>/dev/null || echo "[]") echo "Changed packages: ${CHANGED_JSON}" if [ "${CHANGED_JSON}" = "[]" ]; then @@ -259,11 +262,12 @@ jobs: else echo "has_changes=true" >> "$GITHUB_OUTPUT" - SCOPES=$(echo "${CHANGED_JSON}" | node -e " + echo "${CHANGED_JSON}" | node -e " const pkgs = JSON.parse(require('fs').readFileSync(0,'utf8')); - process.stdout.write(pkgs.map(p => '--scope ' + p.name).join(' ')); - ") - echo "scopes=${SCOPES}" >> "$GITHUB_OUTPUT" + const scopes = pkgs.map(p => '--scope ' + p.name).join(' '); + const names = pkgs.map(p => p.name).join(','); + process.stdout.write('scopes=' + scopes + '\n' + 'names=' + names + '\n'); + " >> "$GITHUB_OUTPUT" fi - name: Build changed packages and their dependencies if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} @@ -285,6 +289,7 @@ jobs: echo "//localhost:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc npx lerna version prerelease \ + --force-publish=${{ steps.lerna-changed.outputs.names }} \ --no-push \ --preid "venv.${{ github.run_number }}" \ --yes From 14757c6e2af8f18cc37c2c2f3b384a6e2c4649cd Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 17:15:29 +0300 Subject: [PATCH 05/33] Fixed lerna changed: full fetch-depth for merge-base with master Made-with: Cursor --- .github/workflows/start-venv.yaml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 62a95e8..f6a3c0d 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -229,10 +229,11 @@ jobs: ref: ${{ inputs.templateAndLibsBranch }} path: _shadow-libs token: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} + fetch-depth: 0 - name: Fetch master ref for lerna comparison if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs - run: git fetch origin master --depth=1 + run: git fetch origin master - name: Install library dependencies if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs @@ -254,7 +255,15 @@ jobs: id: lerna-changed working-directory: _shadow-libs run: | - CHANGED_JSON=$(npx lerna changed --since origin/master --json 2>/dev/null || echo "[]") + set +e + CHANGED_JSON=$(npx lerna changed --since origin/master --json 2>lerna-changed.stderr) + LERNA_EXIT=$? + set -e + if [ "${LERNA_EXIT}" -ne 0 ]; then + echo "::warning::lerna changed exited ${LERNA_EXIT}; stderr:" + cat lerna-changed.stderr || true + CHANGED_JSON="[]" + fi echo "Changed packages: ${CHANGED_JSON}" if [ "${CHANGED_JSON}" = "[]" ]; then From 5ae239b9d5d0402e5a95198b14911cbaf4467e0d Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 19:40:50 +0300 Subject: [PATCH 06/33] Fixed detect: use lerna list --since (changed does not support --since in v6) Made-with: Cursor --- .github/workflows/start-venv.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index f6a3c0d..98aba7d 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -256,12 +256,12 @@ jobs: working-directory: _shadow-libs run: | set +e - CHANGED_JSON=$(npx lerna changed --since origin/master --json 2>lerna-changed.stderr) + CHANGED_JSON=$(npx lerna list --since origin/master --all --json 2>lerna-list.stderr) LERNA_EXIT=$? set -e if [ "${LERNA_EXIT}" -ne 0 ]; then - echo "::warning::lerna changed exited ${LERNA_EXIT}; stderr:" - cat lerna-changed.stderr || true + echo "::warning::lerna list --since exited ${LERNA_EXIT}; stderr:" + cat lerna-list.stderr || true CHANGED_JSON="[]" fi echo "Changed packages: ${CHANGED_JSON}" From 1f4cd0408a5877c922c2a698fffb80eb36112cc7 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 19:50:33 +0300 Subject: [PATCH 07/33] Improved Verdaccio build to use `yarn build:ci` (Nx affected) matching template-and-libs CI Made-with: Cursor --- .github/workflows/start-venv.yaml | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 98aba7d..48f0a13 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -230,7 +230,7 @@ jobs: path: _shadow-libs token: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} fetch-depth: 0 - - name: Fetch master ref for lerna comparison + - name: Fetch master ref for affected comparison if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs run: git fetch origin master @@ -270,20 +270,16 @@ jobs: echo "has_changes=false" >> "$GITHUB_OUTPUT" else echo "has_changes=true" >> "$GITHUB_OUTPUT" - - echo "${CHANGED_JSON}" | node -e " + NAMES=$(echo "${CHANGED_JSON}" | node -e " const pkgs = JSON.parse(require('fs').readFileSync(0,'utf8')); - const scopes = pkgs.map(p => '--scope ' + p.name).join(' '); - const names = pkgs.map(p => p.name).join(','); - process.stdout.write('scopes=' + scopes + '\n' + 'names=' + names + '\n'); - " >> "$GITHUB_OUTPUT" + process.stdout.write(pkgs.map(p => p.name).join(',')); + ") + echo "names=${NAMES}" >> "$GITHUB_OUTPUT" fi - - name: Build changed packages and their dependencies + - name: Build affected packages if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} working-directory: _shadow-libs - run: | - echo "Building: ${{ steps.lerna-changed.outputs.scopes }}" - npx lerna run build --no-cache ${{ steps.lerna-changed.outputs.scopes }} --include-dependencies + run: yarn build:ci - name: Register Verdaccio user and token if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} run: | @@ -312,7 +308,7 @@ jobs: run: rm -rf _shadow-libs - name: Check Docker Image id: check-image - if: ${{ !inputs.useVerdaccio }} + if: ${{ !inputs.useVerdaccio || steps.lerna-changed.outputs.has_changes != 'true' }} run: | if docker manifest inspect ${{fromJSON(steps.params.outputs.result).venvImage}} > /dev/null 2>&1; then echo "Docker image exists, no need to build the image" @@ -324,7 +320,7 @@ jobs: - name: Generate npmrc run: | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc - if [ "${{ inputs.useVerdaccio }}" = "true" ]; then + if [ "${{ inputs.useVerdaccio }}" = "true" ] && [ "${{ steps.lerna-changed.outputs.has_changes }}" = "true" ]; then echo '@frontegg:registry=http://localhost:4873' >> .npmrc echo '//localhost:4873/:_authToken=fake-token' >> .npmrc fi @@ -340,7 +336,7 @@ jobs: NPM_TOKEN=${{ secrets.NPM_TOKEN }} - name: Build and push (Verdaccio) uses: docker/build-push-action@v6 - if: ${{ inputs.useVerdaccio }} + if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} with: context: . push: true From 7deb05e84a59103a022c65a3b5b6862a39f8d530 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 20:21:13 +0300 Subject: [PATCH 08/33] Improved Verdaccio venv with targeted git fetch and yarn up for shadow packages Made-with: Cursor --- .github/workflows/start-venv.yaml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 48f0a13..b579de3 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -229,11 +229,25 @@ jobs: ref: ${{ inputs.templateAndLibsBranch }} path: _shadow-libs token: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} - fetch-depth: 0 - - name: Fetch master ref for affected comparison + fetch-depth: 1 + fetch-tags: false + - name: Fetch branch and master for affected comparison if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs - run: git fetch origin master + env: + TARGET_BRANCH: ${{ inputs.templateAndLibsBranch }} + run: | + REFSPEC_MASTER="+refs/heads/master:refs/remotes/origin/master" + REFSPEC_BRANCH="+refs/heads/${TARGET_BRANCH}:refs/remotes/origin/${TARGET_BRANCH}" + git fetch --no-tags --depth=50 origin "${REFSPEC_MASTER}" "${REFSPEC_BRANCH}" + for attempt in $(seq 1 20); do + if git merge-base HEAD origin/master > /dev/null; then + exit 0 + fi + git fetch --no-tags --deepen=50 origin "${REFSPEC_MASTER}" "${REFSPEC_BRANCH}" + done + echo "::error::Unable to find merge-base between ${TARGET_BRANCH} and master after deepening fetch history" + exit 1 - name: Install library dependencies if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs @@ -324,6 +338,14 @@ jobs: echo '@frontegg:registry=http://localhost:4873' >> .npmrc echo '//localhost:4873/:_authToken=fake-token' >> .npmrc fi + - name: Bump lockfile to Verdaccio packages + if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} + run: | + IFS=',' read -ra PKGS <<< "${{ steps.lerna-changed.outputs.names }}" + for pkg in "${PKGS[@]}"; do + echo "Upgrading ${pkg} from Verdaccio" + yarn up "${pkg}" + done - name: Build and push uses: docker/build-push-action@v6 if: ${{ steps.check-image.outputs.image-exist == 'false' }} From 6789f7af62d7b73d37936d5898835a62b6ad9809 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 20:38:32 +0300 Subject: [PATCH 09/33] Fixed Verdaccio lockfile bump with explicit version and npm package-lock support Made-with: Cursor --- .github/workflows/start-venv.yaml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index b579de3..6eef7c4 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -303,6 +303,7 @@ jobs: echo "VERDACCIO_NPM_TOKEN=$(echo "${REG_BODY}" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).token")" >> "$GITHUB_ENV" - name: Publish changed packages to Verdaccio if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} + id: publish-shadow working-directory: _shadow-libs run: | echo "//localhost:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc @@ -313,6 +314,9 @@ jobs: --preid "venv.${{ github.run_number }}" \ --yes + SHADOW_VERSION="$(node -p "require('./lerna.json').version")" + echo "published_version=${SHADOW_VERSION}" >> "$GITHUB_OUTPUT" + npx lerna publish from-package \ --registry http://localhost:4873 \ --no-verify-access \ @@ -340,11 +344,32 @@ jobs: fi - name: Bump lockfile to Verdaccio packages if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} + env: + SHADOW_VERSION: ${{ steps.publish-shadow.outputs.published_version }} run: | + if [ -z "${SHADOW_VERSION}" ]; then + echo "::error::Missing published Verdaccio version" + exit 1 + fi + if [ -f yarn.lock ]; then + LOCKFILE="yarn.lock" + upgrade_cmd() { yarn up "$1@${SHADOW_VERSION}"; } + elif [ -f package-lock.json ]; then + LOCKFILE="package-lock.json" + upgrade_cmd() { npm install "$1@${SHADOW_VERSION}"; } + else + echo "::warning::No yarn.lock or package-lock.json found; skipping lockfile bump" + exit 0 + fi + echo "Detected ${LOCKFILE}" IFS=',' read -ra PKGS <<< "${{ steps.lerna-changed.outputs.names }}" for pkg in "${PKGS[@]}"; do - echo "Upgrading ${pkg} from Verdaccio" - yarn up "${pkg}" + if ! grep -qF "${pkg}" "${LOCKFILE}"; then + echo "Skipping ${pkg}; not referenced in ${LOCKFILE}" + continue + fi + echo "Upgrading ${pkg} to ${SHADOW_VERSION}" + upgrade_cmd "${pkg}" done - name: Build and push uses: docker/build-push-action@v6 From be68b4033cc3e27390093a43bffa04bc8c594bb8 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 20:47:28 +0300 Subject: [PATCH 10/33] Fixed Yarn Berry resolving @frontegg from Verdaccio during lockfile bump Made-with: Cursor --- .github/workflows/start-venv.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 6eef7c4..e8c78aa 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -353,6 +353,10 @@ jobs: fi if [ -f yarn.lock ]; then LOCKFILE="yarn.lock" + # Yarn Berry reads scoped registry from .yarnrc.yml (npmScopes), not from .npmrc; without this, + # yarn up resolves @frontegg to registry.npmjs.org and the prerelease version 404s. + yarn config set npmScopes.frontegg.npmRegistryServer "http://localhost:4873" + yarn config set npmScopes.frontegg.npmAuthToken "fake-token" upgrade_cmd() { yarn up "$1@${SHADOW_VERSION}"; } elif [ -f package-lock.json ]; then LOCKFILE="package-lock.json" From 21d449852e0bd93f323c2cd9bbad22d281b30d8a Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 20:57:11 +0300 Subject: [PATCH 11/33] Improved Verdaccio lockfile bump using resolutions and overrides Made-with: Cursor --- .github/workflows/start-venv.yaml | 40 ++++++++++++++++--------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index e8c78aa..cfee270 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -351,30 +351,32 @@ jobs: echo "::error::Missing published Verdaccio version" exit 1 fi - if [ -f yarn.lock ]; then - LOCKFILE="yarn.lock" - # Yarn Berry reads scoped registry from .yarnrc.yml (npmScopes), not from .npmrc; without this, - # yarn up resolves @frontegg to registry.npmjs.org and the prerelease version 404s. + # Yarn Berry ignores .npmrc scoped registries; patch .yarnrc.yml when present + if [ -f .yarnrc.yml ]; then yarn config set npmScopes.frontegg.npmRegistryServer "http://localhost:4873" yarn config set npmScopes.frontegg.npmAuthToken "fake-token" - upgrade_cmd() { yarn up "$1@${SHADOW_VERSION}"; } + fi + # Pin changed packages via resolutions (Yarn 1 + Berry) and overrides (npm) + node -e " + const fs = require('fs'); + const pkg = JSON.parse(fs.readFileSync('package.json','utf8')); + const names = '${{ steps.lerna-changed.outputs.names }}'.split(','); + const version = process.env.SHADOW_VERSION; + const pins = {}; + names.forEach(n => { pins[n] = version; }); + pkg.resolutions = { ...pkg.resolutions, ...pins }; + pkg.overrides = { ...pkg.overrides, ...pins }; + fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); + console.log('Pinned packages:', JSON.stringify(pins)); + " + # Re-install to update lockfile with pinned versions + if [ -f yarn.lock ]; then + YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install elif [ -f package-lock.json ]; then - LOCKFILE="package-lock.json" - upgrade_cmd() { npm install "$1@${SHADOW_VERSION}"; } + npm install else - echo "::warning::No yarn.lock or package-lock.json found; skipping lockfile bump" - exit 0 + echo "::warning::No lockfile found; skipping install" fi - echo "Detected ${LOCKFILE}" - IFS=',' read -ra PKGS <<< "${{ steps.lerna-changed.outputs.names }}" - for pkg in "${PKGS[@]}"; do - if ! grep -qF "${pkg}" "${LOCKFILE}"; then - echo "Skipping ${pkg}; not referenced in ${LOCKFILE}" - continue - fi - echo "Upgrading ${pkg} to ${SHADOW_VERSION}" - upgrade_cmd "${pkg}" - done - name: Build and push uses: docker/build-push-action@v6 if: ${{ steps.check-image.outputs.image-exist == 'false' }} From 393f14a3a00af1c3c6886ecb977eab54e289c9a4 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 21:08:19 +0300 Subject: [PATCH 12/33] Fixed Yarn Berry Verdaccio whitelist via YAML merge for localhost http Made-with: Cursor --- .github/workflows/start-venv.yaml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index cfee270..9621236 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -351,10 +351,22 @@ jobs: echo "::error::Missing published Verdaccio version" exit 1 fi - # Yarn Berry ignores .npmrc scoped registries; patch .yarnrc.yml when present + # Yarn Berry ignores .npmrc scoped registries; patch .yarnrc.yml when present. + # http://localhost also needs unsafeHttpWhitelist as a real YAML list (yarn config set cannot set arrays). if [ -f .yarnrc.yml ]; then - yarn config set npmScopes.frontegg.npmRegistryServer "http://localhost:4873" - yarn config set npmScopes.frontegg.npmAuthToken "fake-token" + ruby -ryaml -e " + f = '.yarnrc.yml' + c = YAML.load(File.read(f)) || {} + c['npmScopes'] ||= {} + c['npmScopes']['frontegg'] = { + 'npmRegistryServer' => 'http://localhost:4873', + 'npmAuthToken' => 'fake-token' + } + wl = c['unsafeHttpWhitelist'] + wl = wl.is_a?(Array) ? wl : [] + c['unsafeHttpWhitelist'] = (wl + ['localhost']).uniq + File.write(f, c.to_yaml) + " fi # Pin changed packages via resolutions (Yarn 1 + Berry) and overrides (npm) node -e " From 922435c260f96af5afc688a595fa43b8f67e0019 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 21:35:13 +0300 Subject: [PATCH 13/33] Fixed Verdaccio IPv6 ECONNREFUSED by using 127.0.0.1 instead of localhost Made-with: Cursor --- .github/workflows/start-venv.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 9621236..1cd6519 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -210,9 +210,9 @@ jobs: -v /tmp/verdaccio/config.yaml:/verdaccio/conf/config.yaml \ verdaccio/verdaccio for i in $(seq 1 30); do - curl -sf http://localhost:4873/-/ping && break || sleep 1 + curl -sf http://127.0.0.1:4873/-/ping && break || sleep 1 done - curl -sf http://localhost:4873/-/ping || { echo "ERROR: Verdaccio did not start"; exit 1; } + curl -sf http://127.0.0.1:4873/-/ping || { echo "ERROR: Verdaccio did not start"; exit 1; } - name: Enable Corepack if: ${{ inputs.useVerdaccio }} run: corepack enable @@ -297,7 +297,7 @@ jobs: - name: Register Verdaccio user and token if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} run: | - REG_BODY="$(curl -sf -X PUT "http://localhost:4873/-/user/org.couchdb.user:shadow" \ + REG_BODY="$(curl -sf -X PUT "http://127.0.0.1:4873/-/user/org.couchdb.user:shadow" \ -H "Content-Type: application/json" \ -d '{"name":"shadow","password":"shadow","email":"shadow@frontegg.com","type":"user"}')" echo "VERDACCIO_NPM_TOKEN=$(echo "${REG_BODY}" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).token")" >> "$GITHUB_ENV" @@ -306,7 +306,7 @@ jobs: id: publish-shadow working-directory: _shadow-libs run: | - echo "//localhost:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc + echo "//127.0.0.1:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc npx lerna version prerelease \ --force-publish=${{ steps.lerna-changed.outputs.names }} \ @@ -318,7 +318,7 @@ jobs: echo "published_version=${SHADOW_VERSION}" >> "$GITHUB_OUTPUT" npx lerna publish from-package \ - --registry http://localhost:4873 \ + --registry http://127.0.0.1:4873 \ --no-verify-access \ --yes - name: Clean up shadow libs from build context @@ -339,8 +339,8 @@ jobs: run: | echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc if [ "${{ inputs.useVerdaccio }}" = "true" ] && [ "${{ steps.lerna-changed.outputs.has_changes }}" = "true" ]; then - echo '@frontegg:registry=http://localhost:4873' >> .npmrc - echo '//localhost:4873/:_authToken=fake-token' >> .npmrc + echo '@frontegg:registry=http://127.0.0.1:4873' >> .npmrc + echo '//127.0.0.1:4873/:_authToken=fake-token' >> .npmrc fi - name: Bump lockfile to Verdaccio packages if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes == 'true' }} @@ -359,12 +359,12 @@ jobs: c = YAML.load(File.read(f)) || {} c['npmScopes'] ||= {} c['npmScopes']['frontegg'] = { - 'npmRegistryServer' => 'http://localhost:4873', + 'npmRegistryServer' => 'http://127.0.0.1:4873', 'npmAuthToken' => 'fake-token' } wl = c['unsafeHttpWhitelist'] wl = wl.is_a?(Array) ? wl : [] - c['unsafeHttpWhitelist'] = (wl + ['localhost']).uniq + c['unsafeHttpWhitelist'] = (wl + ['127.0.0.1']).uniq File.write(f, c.to_yaml) " fi From 0aff48f27247fa56fa8c991dcae697d32033fdfc Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 21:45:50 +0300 Subject: [PATCH 14/33] Fixed buildx network isolation preventing Docker build from reaching Verdaccio Made-with: Cursor --- .github/workflows/start-venv.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 1cd6519..4da4683 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -169,6 +169,8 @@ jobs: uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + with: + driver-opts: network=host - name: Login to Docker Hub uses: docker/login-action@v3 with: From ed9bb274db1e315bb6efa760216c413f12121b54 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Wed, 8 Apr 2026 22:58:41 +0300 Subject: [PATCH 15/33] Fixed lockfile bump using yarn up/upgrade/npm install instead of resolutions Made-with: Cursor --- .github/workflows/start-venv.yaml | 48 +++++++++++++++++-------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 4da4683..d894d93 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -353,9 +353,10 @@ jobs: echo "::error::Missing published Verdaccio version" exit 1 fi - # Yarn Berry ignores .npmrc scoped registries; patch .yarnrc.yml when present. - # http://localhost also needs unsafeHttpWhitelist as a real YAML list (yarn config set cannot set arrays). + IFS=',' read -ra PKGS <<< "${{ steps.lerna-changed.outputs.names }}" if [ -f .yarnrc.yml ]; then + # Yarn Berry: .npmrc scoped registries are ignored; patch .yarnrc.yml directly. + # unsafeHttpWhitelist must be a real YAML list (yarn config set cannot set arrays). ruby -ryaml -e " f = '.yarnrc.yml' c = YAML.load(File.read(f)) || {} @@ -369,27 +370,32 @@ jobs: c['unsafeHttpWhitelist'] = (wl + ['127.0.0.1']).uniq File.write(f, c.to_yaml) " - fi - # Pin changed packages via resolutions (Yarn 1 + Berry) and overrides (npm) - node -e " - const fs = require('fs'); - const pkg = JSON.parse(fs.readFileSync('package.json','utf8')); - const names = '${{ steps.lerna-changed.outputs.names }}'.split(','); - const version = process.env.SHADOW_VERSION; - const pins = {}; - names.forEach(n => { pins[n] = version; }); - pkg.resolutions = { ...pkg.resolutions, ...pins }; - pkg.overrides = { ...pkg.overrides, ...pins }; - fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n'); - console.log('Pinned packages:', JSON.stringify(pins)); - " - # Re-install to update lockfile with pinned versions - if [ -f yarn.lock ]; then - YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install + for pkg in "${PKGS[@]}"; do + if grep -qF "${pkg}" yarn.lock; then + echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" + YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up "${pkg}@${SHADOW_VERSION}" + else + echo "Skipping ${pkg}; not referenced in yarn.lock" + fi + done + elif [ -f yarn.lock ]; then + # Yarn 1: respects .npmrc scoped registries (already set in Generate npmrc step) + for pkg in "${PKGS[@]}"; do + if grep -qF "${pkg}" yarn.lock; then + echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" + yarn upgrade "${pkg}@${SHADOW_VERSION}" + else + echo "Skipping ${pkg}; not referenced in yarn.lock" + fi + done elif [ -f package-lock.json ]; then - npm install + # npm: respects .npmrc scoped registries (already set in Generate npmrc step) + for pkg in "${PKGS[@]}"; do + echo "Bumping ${pkg} to ${SHADOW_VERSION} in package-lock.json" + npm install "${pkg}@${SHADOW_VERSION}" + done else - echo "::warning::No lockfile found; skipping install" + echo "::warning::No lockfile found; skipping lockfile bump" fi - name: Build and push uses: docker/build-push-action@v6 From 82a4deeb1d81489da7cc72518c302d30ffaea7b1 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 08:56:54 +0300 Subject: [PATCH 16/33] Improved Verdaccio venv workflow: credential scoping, input validation, shadow tags Made-with: Cursor --- .github/workflows/start-venv.yaml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index d894d93..533a0d4 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -138,6 +138,11 @@ jobs: matrix: ${{ fromJSON(needs.start-venv.outputs.commits) }} runs-on: ubuntu-latest steps: + - name: Validate Verdaccio inputs + if: ${{ inputs.useVerdaccio && inputs.templateAndLibsBranch == '' }} + run: | + echo "::error::useVerdaccio is true but templateAndLibsBranch is empty" + exit 1 - name: Display Commit name ${{ matrix.commits }} run: | echo Building ${{ matrix.commits }} docker @@ -233,21 +238,29 @@ jobs: token: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} fetch-depth: 1 fetch-tags: false + persist-credentials: false - name: Fetch branch and master for affected comparison if: ${{ inputs.useVerdaccio }} working-directory: _shadow-libs env: TARGET_BRANCH: ${{ inputs.templateAndLibsBranch }} + GH_TOKEN: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} run: | + AUTH="$(printf 'x-access-token:%s' "${GH_TOKEN}" | base64)" + git config --local http.https://github.com/.extraheader "AUTHORIZATION: basic ${AUTH}" + REFSPEC_MASTER="+refs/heads/master:refs/remotes/origin/master" REFSPEC_BRANCH="+refs/heads/${TARGET_BRANCH}:refs/remotes/origin/${TARGET_BRANCH}" git fetch --no-tags --depth=50 origin "${REFSPEC_MASTER}" "${REFSPEC_BRANCH}" for attempt in $(seq 1 20); do if git merge-base HEAD origin/master > /dev/null; then + git config --local --unset http.https://github.com/.extraheader exit 0 fi git fetch --no-tags --deepen=50 origin "${REFSPEC_MASTER}" "${REFSPEC_BRANCH}" done + + git config --local --unset-all http.https://github.com/.extraheader || true echo "::error::Unable to find merge-base between ${TARGET_BRANCH} and master after deepening fetch history" exit 1 - name: Install library dependencies @@ -414,7 +427,9 @@ jobs: context: . push: true network: host - tags: ${{fromJSON(steps.params.outputs.result).image}},${{fromJSON(steps.params.outputs.result).venvImage}} + tags: | + frontegg/${{fromJSON(steps.params.outputs.result).repository}}:shadow-${{github.run_number}}-${{fromJSON(steps.params.outputs.result).shortSha}} + ${{fromJSON(steps.params.outputs.result).venvImage}} build-args: | COMMIT_HASH=${{fromJSON(steps.params.outputs.result).shortSha}} NPM_TOKEN=${{ secrets.NPM_TOKEN }} From bfca17903c3be9bf5dd9b56618ccb8a4834885b8 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 10:22:01 +0300 Subject: [PATCH 17/33] Fixed Verdaccio bump to only upgrade direct package.json dependencies Made-with: Cursor --- .github/workflows/start-venv.yaml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 533a0d4..0cd2ac8 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -384,28 +384,32 @@ jobs: File.write(f, c.to_yaml) " for pkg in "${PKGS[@]}"; do - if grep -qF "${pkg}" yarn.lock; then + if grep -rqF "\"${pkg}\"" --include="package.json" .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up "${pkg}@${SHADOW_VERSION}" else - echo "Skipping ${pkg}; not referenced in yarn.lock" + echo "Skipping ${pkg}; not a direct workspace dependency" fi done elif [ -f yarn.lock ]; then # Yarn 1: respects .npmrc scoped registries (already set in Generate npmrc step) for pkg in "${PKGS[@]}"; do - if grep -qF "${pkg}" yarn.lock; then + if grep -rqF "\"${pkg}\"" --include="package.json" .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" yarn upgrade "${pkg}@${SHADOW_VERSION}" else - echo "Skipping ${pkg}; not referenced in yarn.lock" + echo "Skipping ${pkg}; not a direct workspace dependency" fi done elif [ -f package-lock.json ]; then # npm: respects .npmrc scoped registries (already set in Generate npmrc step) for pkg in "${PKGS[@]}"; do - echo "Bumping ${pkg} to ${SHADOW_VERSION} in package-lock.json" - npm install "${pkg}@${SHADOW_VERSION}" + if grep -rqF "\"${pkg}\"" --include="package.json" .; then + echo "Bumping ${pkg} to ${SHADOW_VERSION} in package-lock.json" + npm install "${pkg}@${SHADOW_VERSION}" + else + echo "Skipping ${pkg}; not a direct workspace dependency" + fi done else echo "::warning::No lockfile found; skipping lockfile bump" From 2bfb64b6f04602be36595382e1451fc84b1c5470 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 10:44:02 +0300 Subject: [PATCH 18/33] Fixed Verdaccio direct-dep check ignoring node_modules and name fields Made-with: Cursor --- .github/workflows/start-venv.yaml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 0cd2ac8..c73e4cb 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -383,8 +383,10 @@ jobs: c['unsafeHttpWhitelist'] = (wl + ['127.0.0.1']).uniq File.write(f, c.to_yaml) " + # Match only dependency-style keys ("pkg": …), not "name": "@scope/pkg" inside node_modules after prior yarn up. for pkg in "${PKGS[@]}"; do - if grep -rqF "\"${pkg}\"" --include="package.json" .; then + if grep -rqF "\"${pkg}\":" --include="package.json" \ + --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up "${pkg}@${SHADOW_VERSION}" else @@ -394,7 +396,8 @@ jobs: elif [ -f yarn.lock ]; then # Yarn 1: respects .npmrc scoped registries (already set in Generate npmrc step) for pkg in "${PKGS[@]}"; do - if grep -rqF "\"${pkg}\"" --include="package.json" .; then + if grep -rqF "\"${pkg}\":" --include="package.json" \ + --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" yarn upgrade "${pkg}@${SHADOW_VERSION}" else @@ -404,7 +407,8 @@ jobs: elif [ -f package-lock.json ]; then # npm: respects .npmrc scoped registries (already set in Generate npmrc step) for pkg in "${PKGS[@]}"; do - if grep -rqF "\"${pkg}\"" --include="package.json" .; then + if grep -rqF "\"${pkg}\":" --include="package.json" \ + --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in package-lock.json" npm install "${pkg}@${SHADOW_VERSION}" else From d1eb315ad53d74eb0837b46adb32a4a54492ebe9 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 14:11:12 +0300 Subject: [PATCH 19/33] Fixed yarn up to use --exact so prerelease versions are always pinned Made-with: Cursor --- .github/workflows/start-venv.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index c73e4cb..294fbf1 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -388,7 +388,7 @@ jobs: if grep -rqF "\"${pkg}\":" --include="package.json" \ --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" - YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up "${pkg}@${SHADOW_VERSION}" + YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up --exact "${pkg}@${SHADOW_VERSION}" else echo "Skipping ${pkg}; not a direct workspace dependency" fi From af4fbda76da7bfb707187ee5208eeef5da27d00d Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 16:30:45 +0300 Subject: [PATCH 20/33] Improved Verdaccio to use patch versions instead of prereleases Made-with: Cursor --- .github/workflows/start-venv.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 294fbf1..d5e849f 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -323,10 +323,9 @@ jobs: run: | echo "//127.0.0.1:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc - npx lerna version prerelease \ + npx lerna version patch \ --force-publish=${{ steps.lerna-changed.outputs.names }} \ --no-push \ - --preid "venv.${{ github.run_number }}" \ --yes SHADOW_VERSION="$(node -p "require('./lerna.json').version")" @@ -388,7 +387,7 @@ jobs: if grep -rqF "\"${pkg}\":" --include="package.json" \ --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" - YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up --exact "${pkg}@${SHADOW_VERSION}" + YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up "${pkg}@${SHADOW_VERSION}" else echo "Skipping ${pkg}; not a direct workspace dependency" fi From 633847ada763518d90c119bdf5c154945467311d Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 16:34:50 +0300 Subject: [PATCH 21/33] Added --exact to yarn up so venv version is visible in package.json Made-with: Cursor --- .github/workflows/start-venv.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index d5e849f..1c8db1e 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -387,7 +387,7 @@ jobs: if grep -rqF "\"${pkg}\":" --include="package.json" \ --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" - YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up "${pkg}@${SHADOW_VERSION}" + YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up --exact "${pkg}@${SHADOW_VERSION}" else echo "Skipping ${pkg}; not a direct workspace dependency" fi From 6ad24883ddadfed9c380043ae4b684ce56198bc8 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 21:35:23 +0300 Subject: [PATCH 22/33] Added Verdaccio venv appVersion bump and venv-shadow image tag for Argo redeploy Made-with: Cursor --- .github/workflows/start-venv.yaml | 32 ++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 1c8db1e..fb54442 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -128,6 +128,34 @@ jobs: const result = { commits: splitString.map(x => x.toString()) }; console.log(`result: ${JSON.stringify(result)}`); return JSON.stringify(result); + - name: Update venv repo appVersion for Verdaccio + if: ${{ inputs.useVerdaccio && steps.venv-actions.outputs.commits != '' }} + working-directory: ./venv + run: | + IFS=',' read -ra ENTRIES <<< "${{ steps.venv-actions.outputs.commits }}" + CHANGED=false + for entry in "${ENTRIES[@]}"; do + HASH="${entry##*:}" + SHORT_SHA="${HASH:0:7}" + NEW_APP_VERSION="shadow-${{ github.run_number }}-${SHORT_SHA}" + echo "Replacing appVersion: ${SHORT_SHA} -> ${NEW_APP_VERSION}" + if grep -rl "appVersion: ${SHORT_SHA}" environments/ 2>/dev/null; then + grep -rl "appVersion: ${SHORT_SHA}" environments/ | xargs sed -i "s|appVersion: ${SHORT_SHA}|appVersion: ${NEW_APP_VERSION}|g" + CHANGED=true + elif grep -rl "appVersion: \"${SHORT_SHA}\"" environments/ 2>/dev/null; then + grep -rl "appVersion: \"${SHORT_SHA}\"" environments/ | xargs sed -i "s|appVersion: \"${SHORT_SHA}\"|appVersion: \"${NEW_APP_VERSION}\"|g" + CHANGED=true + else + echo "::warning::appVersion ${SHORT_SHA} not found in venv environments" + fi + done + if [ "${CHANGED}" = "true" ]; then + git add . + git commit -m "venv: verdaccio appVersion for run ${{ github.run_number }}" + git fetch origin master + git rebase origin/master + git push origin master + fi build-docker: name: Build services docker images for venv @@ -323,9 +351,10 @@ jobs: run: | echo "//127.0.0.1:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> .npmrc - npx lerna version patch \ + npx lerna version prerelease \ --force-publish=${{ steps.lerna-changed.outputs.names }} \ --no-push \ + --preid "venv.${{ github.run_number }}" \ --yes SHADOW_VERSION="$(node -p "require('./lerna.json').version")" @@ -436,6 +465,7 @@ jobs: network: host tags: | frontegg/${{fromJSON(steps.params.outputs.result).repository}}:shadow-${{github.run_number}}-${{fromJSON(steps.params.outputs.result).shortSha}} + frontegg/${{fromJSON(steps.params.outputs.result).repository}}:venv-shadow-${{github.run_number}}-${{fromJSON(steps.params.outputs.result).shortSha}} ${{fromJSON(steps.params.outputs.result).venvImage}} build-args: | COMMIT_HASH=${{fromJSON(steps.params.outputs.result).shortSha}} From 0727222dd28a9fabc2363060111632acd0355487 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 21:38:42 +0300 Subject: [PATCH 23/33] Improved shadow tags to use run_id+run_attempt so re-runs also trigger redeploy Made-with: Cursor --- .github/workflows/start-venv.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index fb54442..c6db7cf 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -137,7 +137,7 @@ jobs: for entry in "${ENTRIES[@]}"; do HASH="${entry##*:}" SHORT_SHA="${HASH:0:7}" - NEW_APP_VERSION="shadow-${{ github.run_number }}-${SHORT_SHA}" + NEW_APP_VERSION="shadow-${{ github.run_id }}-${{ github.run_attempt }}-${SHORT_SHA}" echo "Replacing appVersion: ${SHORT_SHA} -> ${NEW_APP_VERSION}" if grep -rl "appVersion: ${SHORT_SHA}" environments/ 2>/dev/null; then grep -rl "appVersion: ${SHORT_SHA}" environments/ | xargs sed -i "s|appVersion: ${SHORT_SHA}|appVersion: ${NEW_APP_VERSION}|g" @@ -151,7 +151,7 @@ jobs: done if [ "${CHANGED}" = "true" ]; then git add . - git commit -m "venv: verdaccio appVersion for run ${{ github.run_number }}" + git commit -m "venv: verdaccio appVersion for run ${{ github.run_id }}-${{ github.run_attempt }}" git fetch origin master git rebase origin/master git push origin master @@ -354,7 +354,7 @@ jobs: npx lerna version prerelease \ --force-publish=${{ steps.lerna-changed.outputs.names }} \ --no-push \ - --preid "venv.${{ github.run_number }}" \ + --preid "venv.${{ github.run_id }}.${{ github.run_attempt }}" \ --yes SHADOW_VERSION="$(node -p "require('./lerna.json').version")" @@ -464,8 +464,8 @@ jobs: push: true network: host tags: | - frontegg/${{fromJSON(steps.params.outputs.result).repository}}:shadow-${{github.run_number}}-${{fromJSON(steps.params.outputs.result).shortSha}} - frontegg/${{fromJSON(steps.params.outputs.result).repository}}:venv-shadow-${{github.run_number}}-${{fromJSON(steps.params.outputs.result).shortSha}} + frontegg/${{fromJSON(steps.params.outputs.result).repository}}:shadow-${{github.run_id}}-${{github.run_attempt}}-${{fromJSON(steps.params.outputs.result).shortSha}} + frontegg/${{fromJSON(steps.params.outputs.result).repository}}:venv-shadow-${{github.run_id}}-${{github.run_attempt}}-${{fromJSON(steps.params.outputs.result).shortSha}} ${{fromJSON(steps.params.outputs.result).venvImage}} build-args: | COMMIT_HASH=${{fromJSON(steps.params.outputs.result).shortSha}} From 2a8e51f234692a35238b88a680f64a22d92a0460 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 21:44:38 +0300 Subject: [PATCH 24/33] Fixed venv appVersion grep to match venv-prefixed format Made-with: Cursor --- .github/workflows/start-venv.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index c6db7cf..0b01b3e 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -137,16 +137,17 @@ jobs: for entry in "${ENTRIES[@]}"; do HASH="${entry##*:}" SHORT_SHA="${HASH:0:7}" + OLD_APP_VERSION="venv-${SHORT_SHA}" NEW_APP_VERSION="shadow-${{ github.run_id }}-${{ github.run_attempt }}-${SHORT_SHA}" - echo "Replacing appVersion: ${SHORT_SHA} -> ${NEW_APP_VERSION}" - if grep -rl "appVersion: ${SHORT_SHA}" environments/ 2>/dev/null; then - grep -rl "appVersion: ${SHORT_SHA}" environments/ | xargs sed -i "s|appVersion: ${SHORT_SHA}|appVersion: ${NEW_APP_VERSION}|g" + echo "Replacing appVersion: ${OLD_APP_VERSION} -> ${NEW_APP_VERSION}" + if grep -rl "appVersion: ${OLD_APP_VERSION}" environments/ 2>/dev/null; then + grep -rl "appVersion: ${OLD_APP_VERSION}" environments/ | xargs sed -i "s|appVersion: ${OLD_APP_VERSION}|appVersion: ${NEW_APP_VERSION}|g" CHANGED=true - elif grep -rl "appVersion: \"${SHORT_SHA}\"" environments/ 2>/dev/null; then - grep -rl "appVersion: \"${SHORT_SHA}\"" environments/ | xargs sed -i "s|appVersion: \"${SHORT_SHA}\"|appVersion: \"${NEW_APP_VERSION}\"|g" + elif grep -rl "appVersion: \"${OLD_APP_VERSION}\"" environments/ 2>/dev/null; then + grep -rl "appVersion: \"${OLD_APP_VERSION}\"" environments/ | xargs sed -i "s|appVersion: \"${OLD_APP_VERSION}\"|appVersion: \"${NEW_APP_VERSION}\"|g" CHANGED=true else - echo "::warning::appVersion ${SHORT_SHA} not found in venv environments" + echo "::warning::appVersion ${OLD_APP_VERSION} not found in venv environments" fi done if [ "${CHANGED}" = "true" ]; then @@ -465,7 +466,6 @@ jobs: network: host tags: | frontegg/${{fromJSON(steps.params.outputs.result).repository}}:shadow-${{github.run_id}}-${{github.run_attempt}}-${{fromJSON(steps.params.outputs.result).shortSha}} - frontegg/${{fromJSON(steps.params.outputs.result).repository}}:venv-shadow-${{github.run_id}}-${{github.run_attempt}}-${{fromJSON(steps.params.outputs.result).shortSha}} ${{fromJSON(steps.params.outputs.result).venvImage}} build-args: | COMMIT_HASH=${{fromJSON(steps.params.outputs.result).shortSha}} From 36104ce74c968a0e06320cb4fbd91280122a43c1 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Thu, 9 Apr 2026 22:49:15 +0300 Subject: [PATCH 25/33] Fixed Verdaccio to only publish actually changed packages, not transitive dependents Made-with: Cursor --- .github/workflows/start-venv.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 0b01b3e..c066cf9 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -314,7 +314,7 @@ jobs: working-directory: _shadow-libs run: | set +e - CHANGED_JSON=$(npx lerna list --since origin/master --all --json 2>lerna-list.stderr) + CHANGED_JSON=$(npx lerna list --since origin/master --all --exclude-dependents --json 2>lerna-list.stderr) LERNA_EXIT=$? set -e if [ "${LERNA_EXIT}" -ne 0 ]; then @@ -361,7 +361,14 @@ jobs: SHADOW_VERSION="$(node -p "require('./lerna.json').version")" echo "published_version=${SHADOW_VERSION}" >> "$GITHUB_OUTPUT" + SCOPE_ARGS="" + IFS=',' read -ra CHANGED_PKGS <<< "${{ steps.lerna-changed.outputs.names }}" + for pkg in "${CHANGED_PKGS[@]}"; do + SCOPE_ARGS="${SCOPE_ARGS} --scope ${pkg}" + done + npx lerna publish from-package \ + ${SCOPE_ARGS} \ --registry http://127.0.0.1:4873 \ --no-verify-access \ --yes From 5d45e5bba8624f4d1611133cc72984545277e92a Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 09:18:21 +0300 Subject: [PATCH 26/33] Fixed Verdaccio publish to use npm publish per-package instead of unsupported lerna --scope Made-with: Cursor --- .github/workflows/start-venv.yaml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index c066cf9..3dca5a4 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -361,17 +361,21 @@ jobs: SHADOW_VERSION="$(node -p "require('./lerna.json').version")" echo "published_version=${SHADOW_VERSION}" >> "$GITHUB_OUTPUT" - SCOPE_ARGS="" + ALL_PKGS_JSON=$(npx lerna list --all --json) IFS=',' read -ra CHANGED_PKGS <<< "${{ steps.lerna-changed.outputs.names }}" for pkg in "${CHANGED_PKGS[@]}"; do - SCOPE_ARGS="${SCOPE_ARGS} --scope ${pkg}" + PKG_DIR=$(echo "${ALL_PKGS_JSON}" | node -e " + const pkgs = JSON.parse(require('fs').readFileSync(0,'utf8')); + const p = pkgs.find(x => x.name === '${pkg}'); + if (p) process.stdout.write(p.location); + ") + if [ -n "${PKG_DIR}" ]; then + echo "Publishing ${pkg} from ${PKG_DIR}" + npm publish "${PKG_DIR}" --registry http://127.0.0.1:4873 + else + echo "::warning::Could not find location for ${pkg}" + fi done - - npx lerna publish from-package \ - ${SCOPE_ARGS} \ - --registry http://127.0.0.1:4873 \ - --no-verify-access \ - --yes - name: Clean up shadow libs from build context if: ${{ inputs.useVerdaccio }} run: rm -rf _shadow-libs From f19272b562f3676bcb8526d2505afffc63cda88c Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 09:50:36 +0300 Subject: [PATCH 27/33] Fixed publish to use lerna from-package for full dep tree, keep exclude-dependents only for yarn up Made-with: Cursor --- .github/workflows/start-venv.yaml | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 3dca5a4..af121e0 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -361,21 +361,10 @@ jobs: SHADOW_VERSION="$(node -p "require('./lerna.json').version")" echo "published_version=${SHADOW_VERSION}" >> "$GITHUB_OUTPUT" - ALL_PKGS_JSON=$(npx lerna list --all --json) - IFS=',' read -ra CHANGED_PKGS <<< "${{ steps.lerna-changed.outputs.names }}" - for pkg in "${CHANGED_PKGS[@]}"; do - PKG_DIR=$(echo "${ALL_PKGS_JSON}" | node -e " - const pkgs = JSON.parse(require('fs').readFileSync(0,'utf8')); - const p = pkgs.find(x => x.name === '${pkg}'); - if (p) process.stdout.write(p.location); - ") - if [ -n "${PKG_DIR}" ]; then - echo "Publishing ${pkg} from ${PKG_DIR}" - npm publish "${PKG_DIR}" --registry http://127.0.0.1:4873 - else - echo "::warning::Could not find location for ${pkg}" - fi - done + npx lerna publish from-package \ + --registry http://127.0.0.1:4873 \ + --no-verify-access \ + --yes - name: Clean up shadow libs from build context if: ${{ inputs.useVerdaccio }} run: rm -rf _shadow-libs From e0dcabe2f5d20d3b2dedef4ab2c8aadf3c9b2a5d Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 10:30:18 +0300 Subject: [PATCH 28/33] Improved Verdaccio setup: pin image to 6.3, use Node 24 for template-and-libs Made-with: Cursor --- .github/workflows/start-venv.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index af121e0..330b628 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -244,7 +244,7 @@ jobs: run: | docker run -d --name verdaccio -p 4873:4873 \ -v /tmp/verdaccio/config.yaml:/verdaccio/conf/config.yaml \ - verdaccio/verdaccio + verdaccio/verdaccio:6.3 for i in $(seq 1 30); do curl -sf http://127.0.0.1:4873/-/ping && break || sleep 1 done @@ -256,7 +256,7 @@ jobs: if: ${{ inputs.useVerdaccio }} uses: actions/setup-node@v4 with: - node-version: "18" + node-version: "24" - name: Checkout template-and-libs if: ${{ inputs.useVerdaccio }} uses: actions/checkout@v4 From 6b54b76989041602ddd611d7a6e453cd0064e776 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 10:32:35 +0300 Subject: [PATCH 29/33] Improved Verdaccio image pin to 6.4 Made-with: Cursor --- .github/workflows/start-venv.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 330b628..2371eb1 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -244,7 +244,7 @@ jobs: run: | docker run -d --name verdaccio -p 4873:4873 \ -v /tmp/verdaccio/config.yaml:/verdaccio/conf/config.yaml \ - verdaccio/verdaccio:6.3 + verdaccio/verdaccio:6.4 for i in $(seq 1 30); do curl -sf http://127.0.0.1:4873/-/ping && break || sleep 1 done From 74fea95426d5f564e9bccd2ddeaff9a86f6b69d4 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 14:20:22 +0300 Subject: [PATCH 30/33] Improved start-venv Verdaccio cleanup: dedup bumps, node yaml patch, summary Made-with: Cursor --- .github/workflows/start-venv.yaml | 106 +++++++++++++++++------------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 2371eb1..53e329f 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -132,6 +132,8 @@ jobs: if: ${{ inputs.useVerdaccio && steps.venv-actions.outputs.commits != '' }} working-directory: ./venv run: | + git config user.email "shadow@frontegg.com" + git config user.name "shadow-agent" IFS=',' read -ra ENTRIES <<< "${{ steps.venv-actions.outputs.commits }}" CHANGED=false for entry in "${ENTRIES[@]}"; do @@ -216,7 +218,7 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: | mkdir -p /tmp/verdaccio - cat > /tmp/verdaccio/config.yaml < /tmp/verdaccio/config.yaml <> "$GITHUB_STEP_SUMMARY" + echo "**Version:** \`${{ steps.publish-shadow.outputs.published_version }}\`" >> "$GITHUB_STEP_SUMMARY" + echo "**Packages bumped in service:**" >> "$GITHUB_STEP_SUMMARY" + IFS=',' read -ra PKGS <<< "${{ steps.lerna-changed.outputs.names }}" + for pkg in "${PKGS[@]}"; do + echo "- \`${pkg}\`" >> "$GITHUB_STEP_SUMMARY" + done - name: Clean up shadow libs from build context if: ${{ inputs.useVerdaccio }} run: rm -rf _shadow-libs + # Non-Verdaccio: reuse an existing image when available. + # Verdaccio builds always push a fresh image with a unique shadow-* tag (see below). - name: Check Docker Image id: check-image if: ${{ !inputs.useVerdaccio || steps.lerna-changed.outputs.has_changes != 'true' }} @@ -395,58 +410,57 @@ jobs: echo "::error::Missing published Verdaccio version" exit 1 fi - IFS=',' read -ra PKGS <<< "${{ steps.lerna-changed.outputs.names }}" + if [ -f .yarnrc.yml ]; then # Yarn Berry: .npmrc scoped registries are ignored; patch .yarnrc.yml directly. - # unsafeHttpWhitelist must be a real YAML list (yarn config set cannot set arrays). - ruby -ryaml -e " - f = '.yarnrc.yml' - c = YAML.load(File.read(f)) || {} - c['npmScopes'] ||= {} - c['npmScopes']['frontegg'] = { - 'npmRegistryServer' => 'http://127.0.0.1:4873', - 'npmAuthToken' => 'fake-token' + node -e " + const fs = require('fs'); + const f = '.yarnrc.yml'; + let lines = fs.readFileSync(f, 'utf8').split('\n'); + // Strip existing npmScopes and unsafeHttpWhitelist blocks + let i = 0, out = []; + while (i < lines.length) { + if (/^(npmScopes|unsafeHttpWhitelist):/.test(lines[i])) { + i++; + while (i < lines.length && /^\s+/.test(lines[i])) i++; + } else { + out.push(lines[i]); + i++; + } } - wl = c['unsafeHttpWhitelist'] - wl = wl.is_a?(Array) ? wl : [] - c['unsafeHttpWhitelist'] = (wl + ['127.0.0.1']).uniq - File.write(f, c.to_yaml) + // Remove trailing blank lines then re-add config + while (out.length && out[out.length - 1].trim() === '') out.pop(); + out.push(''); + out.push('npmScopes:'); + out.push(' frontegg:'); + out.push(' npmRegistryServer: \"http://127.0.0.1:4873\"'); + out.push(' npmAuthToken: \"fake-token\"'); + out.push(''); + out.push('unsafeHttpWhitelist:'); + out.push(' - 127.0.0.1'); + out.push(''); + fs.writeFileSync(f, out.join('\n')); " - # Match only dependency-style keys ("pkg": …), not "name": "@scope/pkg" inside node_modules after prior yarn up. - for pkg in "${PKGS[@]}"; do - if grep -rqF "\"${pkg}\":" --include="package.json" \ - --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then - echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" - YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up --exact "${pkg}@${SHADOW_VERSION}" - else - echo "Skipping ${pkg}; not a direct workspace dependency" - fi - done + BUMP_CMD="YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn up --exact" elif [ -f yarn.lock ]; then - # Yarn 1: respects .npmrc scoped registries (already set in Generate npmrc step) - for pkg in "${PKGS[@]}"; do - if grep -rqF "\"${pkg}\":" --include="package.json" \ - --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then - echo "Bumping ${pkg} to ${SHADOW_VERSION} in yarn.lock" - yarn upgrade "${pkg}@${SHADOW_VERSION}" - else - echo "Skipping ${pkg}; not a direct workspace dependency" - fi - done + BUMP_CMD="yarn upgrade" elif [ -f package-lock.json ]; then - # npm: respects .npmrc scoped registries (already set in Generate npmrc step) - for pkg in "${PKGS[@]}"; do - if grep -rqF "\"${pkg}\":" --include="package.json" \ - --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then - echo "Bumping ${pkg} to ${SHADOW_VERSION} in package-lock.json" - npm install "${pkg}@${SHADOW_VERSION}" - else - echo "Skipping ${pkg}; not a direct workspace dependency" - fi - done + BUMP_CMD="npm install" else echo "::warning::No lockfile found; skipping lockfile bump" + exit 0 fi + + IFS=',' read -ra PKGS <<< "${{ steps.lerna-changed.outputs.names }}" + for pkg in "${PKGS[@]}"; do + if grep -rqF "\"${pkg}\":" --include="package.json" \ + --exclude-dir=node_modules --exclude-dir=_shadow-libs --exclude-dir=.yarn .; then + echo "Bumping ${pkg} to ${SHADOW_VERSION}" + eval "${BUMP_CMD} \"${pkg}@${SHADOW_VERSION}\"" + else + echo "Skipping ${pkg}; not a direct workspace dependency" + fi + done - name: Build and push uses: docker/build-push-action@v6 if: ${{ steps.check-image.outputs.image-exist == 'false' }} From 6b452baf34f56e8934732133191a6b0a1d9253cf Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 17:45:32 +0300 Subject: [PATCH 31/33] Removed Verdaccio test script and README from scripts folder Made-with: Cursor --- scripts/README-verdaccio-test.md | 37 ------- scripts/test-verdaccio-flow.sh | 160 ------------------------------- 2 files changed, 197 deletions(-) delete mode 100644 scripts/README-verdaccio-test.md delete mode 100755 scripts/test-verdaccio-flow.sh diff --git a/scripts/README-verdaccio-test.md b/scripts/README-verdaccio-test.md deleted file mode 100644 index fc80bcc..0000000 --- a/scripts/README-verdaccio-test.md +++ /dev/null @@ -1,37 +0,0 @@ -# Local Verdaccio flow test - -Runs the same Verdaccio config, user registration, clone, build, and selective `lerna publish` flow as [`.github/workflows/start-venv.yaml`](../.github/workflows/start-venv.yaml) (when `useVerdaccio` is true). - -## Prerequisites - -- Docker -- Node.js / npm (for `curl` JSON parsing and `npx lerna`) -- `NPM_TOKEN` with access to private `@frontegg/*` on npmjs (for `yarn install` in template-and-libs and for Verdaccio uplink auth in the generated config) -- `GH_TOKEN` with read access to `frontegg/template-and-libs` - -## Run - -```bash -cd /path/to/workflows -export NPM_TOKEN='...' -export GH_TOKEN='...' # or: export GH_TOKEN="$(gh auth token)" -export TEMPLATE_LIBS_BRANCH='master' # or your PR branch - -# Optional: verify npmjs proxy for a specific package through Verdaccio -export PROXY_CHECK_PACKAGE='@frontegg/some-package' - -# Optional: only run through lerna changed, skip version/publish -# export SKIP_PUBLISH=1 - -bash scripts/test-verdaccio-flow.sh -``` - -## What it checks - -- Verdaccio starts with the explicit `config.yaml` (scoped `@frontegg/*` + `proxy: npmjs`, uplink bearer token). -- User registration via the npm registry HTTP API (non-interactive). -- Clone + `yarn install` + `yarn build:no-cache` on template-and-libs. -- `lerna changed` / publish only when there are changes (no `--force-publish`). -- Optional: `npm view $PROXY_CHECK_PACKAGE --registry http://localhost:4873` exercises the proxy path. - -The temp workdir is removed on exit unless you set `KEEP_WORKDIR=1` for debugging. diff --git a/scripts/test-verdaccio-flow.sh b/scripts/test-verdaccio-flow.sh deleted file mode 100755 index 623ba1a..0000000 --- a/scripts/test-verdaccio-flow.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash -# Local smoke test for the Verdaccio + selective publish flow used in start-venv.yaml. -# Mirrors: .github/workflows/start-venv.yaml (Write Verdaccio config through Publish changed packages) -# -# Required env: -# NPM_TOKEN npm token for uplink proxy to registry.npmjs.org -# GH_TOKEN GitHub PAT with repo read for frontegg/template-and-libs -# TEMPLATE_LIBS_BRANCH branch or ref to clone (e.g. master or your PR branch) -# -# Optional: -# PROXY_CHECK_PACKAGE @frontegg package name to verify npmjs proxy (default: skip if unset) -# SKIP_PUBLISH if set to "1", stop after lerna changed (no version/publish) -# WORKDIR temp root (default: mktemp) - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" - -if [[ -z "${NPM_TOKEN:-}" ]]; then - echo "ERROR: NPM_TOKEN is required" - exit 1 -fi -if [[ -z "${GH_TOKEN:-}" ]]; then - echo "ERROR: GH_TOKEN is required (read access to frontegg/template-and-libs)" - exit 1 -fi -if [[ -z "${TEMPLATE_LIBS_BRANCH:-}" ]]; then - echo "ERROR: TEMPLATE_LIBS_BRANCH is required" - exit 1 -fi - -if ! command -v docker &>/dev/null; then - echo "ERROR: docker is required" - exit 1 -fi - -WORKDIR="${WORKDIR:-$(mktemp -d -t verdaccio-test-XXXXXX)}" -CONFIG_DIR="${WORKDIR}/verdaccio" -SHADOW_LIBS="${WORKDIR}/_shadow-libs" -RUN_ID="${RUN_ID:-$(date +%s)}" - -cleanup() { - docker rm -f verdaccio-test 2>/dev/null || true - if [[ "${KEEP_WORKDIR:-}" != "1" ]]; then - rm -rf "${WORKDIR}" - fi -} -trap cleanup EXIT - -mkdir -p "${CONFIG_DIR}" - -write_verdaccio_config() { - cat > "${CONFIG_DIR}/config.yaml" < Workdir: ${WORKDIR}" -write_verdaccio_config -echo "==> Starting Verdaccio (matches CI config shape)" -docker rm -f verdaccio-test 2>/dev/null || true -docker run -d --name verdaccio-test -p 4873:4873 \ - -v "${CONFIG_DIR}/config.yaml:/verdaccio/conf/config.yaml" \ - verdaccio/verdaccio - -for i in $(seq 1 40); do - if curl -sf http://localhost:4873/-/ping >/dev/null; then - break - fi - if [[ "${i}" -eq 40 ]]; then - echo "ERROR: Verdaccio did not become ready" - exit 1 - fi - sleep 1 -done -echo "==> Verdaccio is up" - -echo "==> Registering Verdaccio user (npm registry API, non-interactive)" -REG_BODY="$(curl -sf -X PUT "http://localhost:4873/-/user/org.couchdb.user:shadow" \ - -H "Content-Type: application/json" \ - -d '{"name":"shadow","password":"shadow","email":"shadow@frontegg.com","type":"user"}')" -VERDACCIO_NPM_TOKEN="$(echo "${REG_BODY}" | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).token")" -export VERDACCIO_NPM_TOKEN -echo "==> Verdaccio npm token acquired for publish" - -echo "==> Cloning template-and-libs @ ${TEMPLATE_LIBS_BRANCH}" -rm -rf "${SHADOW_LIBS}" -git clone --depth 1 -b "${TEMPLATE_LIBS_BRANCH}" \ - "https://x-access-token:${GH_TOKEN}@github.com/frontegg/template-and-libs.git" \ - "${SHADOW_LIBS}" - -cd "${SHADOW_LIBS}" -export YARN_NPM_AUTH_TOKEN="${NPM_TOKEN}" - -echo "==> yarn install" -yarn install --immutable || YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install - -echo "==> yarn build:no-cache" -yarn build:no-cache - -git config user.email "shadow@frontegg.com" -git config user.name "shadow-agent" - -echo "==> lerna changed (json)" -CHANGED_JSON="$(npx lerna changed --json 2>/dev/null || echo "[]")" -echo "${CHANGED_JSON}" - -if [[ "${CHANGED_JSON}" = "[]" ]]; then - echo "==> No changed packages — CI would skip publish; Verdaccio proxies all @frontegg/* from npmjs" -else - if [[ "${SKIP_PUBLISH:-}" = "1" ]]; then - echo "==> SKIP_PUBLISH=1 — stopping before version/publish" - exit 0 - fi - echo "//localhost:4873/:_authToken=${VERDACCIO_NPM_TOKEN}" >> "${SHADOW_LIBS}/.npmrc" - - echo "==> lerna version + publish (no --force-publish)" - npx lerna version prerelease \ - --no-push \ - --no-git-tag-version \ - --preid "local.${RUN_ID}" \ - --yes - - npx lerna publish from-git \ - --registry http://localhost:4873 \ - --no-verify-access \ - --yes -fi - -echo "==> Smoke: registry responds" -curl -sf "http://localhost:4873/-/ping" | head -c 200 || true -echo - -if [[ -n "${PROXY_CHECK_PACKAGE:-}" ]]; then - echo "==> Proxy check: npm view ${PROXY_CHECK_PACKAGE} via Verdaccio" - npm view "${PROXY_CHECK_PACKAGE}" version --registry http://localhost:4873 -fi - -echo "==> OK — Verdaccio config, clone, build, and publish/proxy path succeeded" -echo " Repo root reference: ${REPO_ROOT}" From 6013780e656ff8d62e6b19491dcabf884ba6e629 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 21:01:23 +0300 Subject: [PATCH 32/33] Fixed git auth header when base64 wraps long tokens Made-with: Cursor --- .github/workflows/start-venv.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index 53e329f..b802391 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -276,7 +276,7 @@ jobs: TARGET_BRANCH: ${{ inputs.templateAndLibsBranch }} GH_TOKEN: ${{ secrets.GH_REPOSITORY_ADMIN_TOKEN }} run: | - AUTH="$(printf 'x-access-token:%s' "${GH_TOKEN}" | base64)" + AUTH="$(printf 'x-access-token:%s' "${GH_TOKEN}" | base64 | tr -d '\n')" git config --local http.https://github.com/.extraheader "AUTHORIZATION: basic ${AUTH}" REFSPEC_MASTER="+refs/heads/master:refs/remotes/origin/master" From b2c67d4651f059adfd20de78bb5b9e8bf63149e9 Mon Sep 17 00:00:00 2001 From: AlexFrontegg Date: Fri, 10 Apr 2026 21:51:06 +0300 Subject: [PATCH 33/33] Fixed shadow Docker tag when Verdaccio has no library changes Made-with: Cursor --- .github/workflows/start-venv.yaml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/start-venv.yaml b/.github/workflows/start-venv.yaml index b802391..15c1be0 100644 --- a/.github/workflows/start-venv.yaml +++ b/.github/workflows/start-venv.yaml @@ -250,14 +250,14 @@ jobs: curl -sf http://127.0.0.1:4873/-/ping && break || sleep 1 done curl -sf http://127.0.0.1:4873/-/ping || { echo "ERROR: Verdaccio did not start"; exit 1; } - - name: Enable Corepack - if: ${{ inputs.useVerdaccio }} - run: corepack enable - name: Setup Node if: ${{ inputs.useVerdaccio }} uses: actions/setup-node@v4 with: node-version: "24" + - name: Enable Corepack + if: ${{ inputs.useVerdaccio }} + run: corepack enable - name: Checkout template-and-libs if: ${{ inputs.useVerdaccio }} uses: actions/checkout@v4 @@ -484,6 +484,12 @@ jobs: build-args: | COMMIT_HASH=${{fromJSON(steps.params.outputs.result).shortSha}} NPM_TOKEN=${{ secrets.NPM_TOKEN }} + - name: Push shadow tag (Verdaccio, no library changes) + if: ${{ inputs.useVerdaccio && steps.lerna-changed.outputs.has_changes != 'true' }} + run: | + docker buildx imagetools create \ + --tag frontegg/${{fromJSON(steps.params.outputs.result).repository}}:shadow-${{github.run_id}}-${{github.run_attempt}}-${{fromJSON(steps.params.outputs.result).shortSha}} \ + ${{fromJSON(steps.params.outputs.result).venvImage}} check-build-docker-results: if: ${{ always() }}