mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
ci: switch from Nexus to Verdaccio for npm patch registry in CI
Nexus takes 5+ minutes cold-start; Verdaccio starts in ~2 seconds. Verdaccio serves patched packages and proxies everything else to npmjs.org. Nexus remains the local dev registry for Docker images and Conan packages. - Replace composite action Nexus startup with Verdaccio (npx verdaccio) - Update @esbuild-kit:registry in .npmrc from :8091/repository/npm-group/ to :4873 - Update publish-npm-patches.sh to support --verdaccio / --nexus flags with auto-detection (checks Nexus first, falls back to Verdaccio) - Add deployment/verdaccio.yaml config for local dev use Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
86
.github/actions/setup-npm/action.yml
vendored
86
.github/actions/setup-npm/action.yml
vendored
@@ -1,5 +1,5 @@
|
||||
name: 'Setup npm with Nexus'
|
||||
description: 'Starts Nexus, publishes patched packages, then runs npm install'
|
||||
name: 'Setup npm with local registry'
|
||||
description: 'Starts Verdaccio, publishes patched packages, then runs npm install'
|
||||
|
||||
inputs:
|
||||
node-version:
|
||||
@@ -15,47 +15,57 @@ runs:
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
|
||||
- name: Cache Nexus data
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/nexus-data
|
||||
key: nexus-data-v1-${{ hashFiles('deployment/npm-patches/**', 'deployment/nexus-init.sh') }}
|
||||
restore-keys: |
|
||||
nexus-data-v1-
|
||||
|
||||
- name: Start Nexus
|
||||
- name: Start Verdaccio and publish patched packages
|
||||
shell: bash
|
||||
run: |
|
||||
docker run -d --name nexus \
|
||||
-p 8091:8081 \
|
||||
-v /tmp/nexus-data:/nexus-data \
|
||||
--platform linux/amd64 \
|
||||
sonatype/nexus3:3.75.0
|
||||
echo "Nexus starting..."
|
||||
# Install and start Verdaccio (lightweight npm registry, ~2s startup)
|
||||
npm install -g verdaccio@6 --silent
|
||||
|
||||
- name: Wait for Nexus
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Waiting for Nexus to be healthy (up to 3 minutes)..."
|
||||
timeout 180 bash -c '
|
||||
until curl -sf http://localhost:8091/service/rest/v1/status -u admin:nexus >/dev/null 2>&1 || \
|
||||
curl -sf http://localhost:8091/service/rest/v1/status >/dev/null 2>&1; do
|
||||
echo " still waiting..."
|
||||
sleep 10
|
||||
done
|
||||
'
|
||||
echo "Nexus is up"
|
||||
mkdir -p /tmp/verdaccio-storage
|
||||
cat > /tmp/verdaccio.yaml << 'VERDACCIO_EOF'
|
||||
storage: /tmp/verdaccio-storage
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
timeout: 60s
|
||||
max_fails: 3
|
||||
packages:
|
||||
'@esbuild-kit/*':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: npmjs
|
||||
'**':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: npmjs
|
||||
server:
|
||||
keepAliveTimeout: 60
|
||||
log:
|
||||
type: stdout
|
||||
format: pretty
|
||||
level: warn
|
||||
listen: 0.0.0.0:4873
|
||||
VERDACCIO_EOF
|
||||
|
||||
- name: Initialise Nexus (npm repos)
|
||||
shell: bash
|
||||
env:
|
||||
NEXUS_URL: http://localhost:8091
|
||||
NEXUS_ADMIN_NEW_PASS: nexus
|
||||
run: bash deployment/nexus-ci-init.sh
|
||||
verdaccio --config /tmp/verdaccio.yaml &
|
||||
VERDACCIO_PID=$!
|
||||
echo "Verdaccio PID: $VERDACCIO_PID"
|
||||
|
||||
- name: Publish patched npm packages
|
||||
shell: bash
|
||||
run: bash deployment/publish-npm-patches.sh
|
||||
# Wait for Verdaccio to be ready (usually <3s)
|
||||
timeout 30 bash -c 'until curl -sf http://localhost:4873/-/ping >/dev/null 2>&1; do sleep 1; done'
|
||||
echo "Verdaccio ready"
|
||||
|
||||
# Publish all patched tarballs
|
||||
PATCHES_DIR="deployment/npm-patches"
|
||||
for tarball in "$PATCHES_DIR"/*.tgz; do
|
||||
[ -f "$tarball" ] || continue
|
||||
echo "Publishing $tarball..."
|
||||
npm publish "$tarball" \
|
||||
--registry http://localhost:4873 \
|
||||
--tag patched \
|
||||
2>&1 | grep -v "^npm notice" || true
|
||||
done
|
||||
echo "Patched packages published to Verdaccio"
|
||||
|
||||
- name: Install npm dependencies
|
||||
shell: bash
|
||||
|
||||
9
.npmrc
9
.npmrc
@@ -42,8 +42,9 @@ workspaces-update=true
|
||||
# These are documented in package.json engines field
|
||||
# Current: Node 22.22.1, npm 11.11.0
|
||||
|
||||
# SCOPED NEXUS REGISTRY - @esbuild-kit patched packages
|
||||
# Local dev: cd deployment && docker compose -f docker-compose.nexus.yml up -d
|
||||
# SCOPED VERDACCIO REGISTRY - @esbuild-kit patched packages
|
||||
# Local dev: npx verdaccio --config deployment/verdaccio.yaml &
|
||||
# bash deployment/publish-npm-patches.sh --verdaccio
|
||||
# CI: started automatically via .github/actions/setup-npm composite action
|
||||
@esbuild-kit:registry=http://localhost:8091/repository/npm-group/
|
||||
//localhost:8091/repository/npm-group/:_auth=YWRtaW46bmV4dXM=
|
||||
@esbuild-kit:registry=http://localhost:4873/
|
||||
//localhost:4873/:_authToken=
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# Publish patched npm packages to local Nexus registry.
|
||||
# Publish patched npm packages to a local registry (Nexus or Verdaccio).
|
||||
#
|
||||
# These packages fix vulnerabilities in bundled transitive dependencies
|
||||
# that npm overrides cannot reach (e.g. minimatch/tar inside the npm package).
|
||||
#
|
||||
# Prerequisites:
|
||||
# - Nexus running: docker compose -f docker-compose.nexus.yml up -d
|
||||
# - nexus-init completed (npm-hosted repo exists)
|
||||
# Prerequisites (choose one):
|
||||
# Nexus: docker compose -f docker-compose.nexus.yml up -d
|
||||
# Verdaccio: npx verdaccio --config deployment/verdaccio.yaml &
|
||||
#
|
||||
# Usage:
|
||||
# ./publish-npm-patches.sh
|
||||
# ./publish-npm-patches.sh # auto-detect (Nexus first, Verdaccio fallback)
|
||||
# ./publish-npm-patches.sh --verdaccio # force Verdaccio on :4873
|
||||
# ./publish-npm-patches.sh --nexus # force Nexus on :8091
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@@ -18,10 +20,30 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||||
|
||||
# Parse flags
|
||||
USE_VERDACCIO=false
|
||||
USE_NEXUS=false
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--verdaccio) USE_VERDACCIO=true ;;
|
||||
--nexus) USE_NEXUS=true ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Auto-detect: try Nexus first, fall back to Verdaccio
|
||||
if ! $USE_VERDACCIO && ! $USE_NEXUS; then
|
||||
if curl -sf http://localhost:8091/service/rest/v1/status -u admin:nexus >/dev/null 2>&1; then
|
||||
USE_NEXUS=true
|
||||
else
|
||||
USE_VERDACCIO=true
|
||||
fi
|
||||
fi
|
||||
|
||||
NEXUS_URL="${NEXUS_URL:-http://localhost:8091}"
|
||||
NEXUS_NPM_HOSTED="${NEXUS_URL}/repository/npm-hosted/"
|
||||
NEXUS_USER="${NEXUS_USER:-admin}"
|
||||
NEXUS_PASS="${NEXUS_PASS:-nexus}"
|
||||
VERDACCIO_URL="${VERDACCIO_URL:-http://localhost:4873}"
|
||||
|
||||
# Packages to patch — version must be the exact fixed version
|
||||
PATCHES=(
|
||||
@@ -42,20 +64,35 @@ log() { echo -e "${GREEN}[npm-patch]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[npm-patch]${NC} $*"; }
|
||||
fail() { echo -e "${RED}[npm-patch]${NC} $*"; exit 1; }
|
||||
|
||||
# Verify Nexus is reachable
|
||||
log "Checking Nexus at $NEXUS_URL..."
|
||||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" "$NEXUS_URL/service/rest/v1/status" -u "$NEXUS_USER:$NEXUS_PASS")
|
||||
if [ "$HTTP" != "200" ]; then
|
||||
fail "Cannot reach Nexus (HTTP $HTTP). Is it running?"
|
||||
fi
|
||||
log "Nexus is up"
|
||||
|
||||
# Configure npm auth for Nexus hosted repo
|
||||
NEXUS_AUTH=$(echo -n "$NEXUS_USER:$NEXUS_PASS" | base64)
|
||||
NPM_RC="$WORK_DIR/.npmrc"
|
||||
cat > "$NPM_RC" <<EOF
|
||||
|
||||
if $USE_NEXUS; then
|
||||
log "Using Nexus at $NEXUS_URL..."
|
||||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" "$NEXUS_URL/service/rest/v1/status" -u "$NEXUS_USER:$NEXUS_PASS")
|
||||
if [ "$HTTP" != "200" ]; then
|
||||
fail "Cannot reach Nexus (HTTP $HTTP). Is it running?"
|
||||
fi
|
||||
log "Nexus is up"
|
||||
NEXUS_AUTH=$(echo -n "$NEXUS_USER:$NEXUS_PASS" | base64)
|
||||
cat > "$NPM_RC" <<EOF
|
||||
//$(echo "$NEXUS_NPM_HOSTED" | sed 's|https\?://||'):_auth=$NEXUS_AUTH
|
||||
EOF
|
||||
PUBLISH_REGISTRY="$NEXUS_NPM_HOSTED"
|
||||
PUBLISH_ARGS="--userconfig $NPM_RC"
|
||||
else
|
||||
log "Using Verdaccio at $VERDACCIO_URL..."
|
||||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" "$VERDACCIO_URL/-/ping")
|
||||
if [ "$HTTP" != "200" ]; then
|
||||
fail "Cannot reach Verdaccio (HTTP $HTTP). Start with: npx verdaccio --config deployment/verdaccio.yaml"
|
||||
fi
|
||||
log "Verdaccio is up"
|
||||
cat > "$NPM_RC" <<EOF
|
||||
registry=$VERDACCIO_URL/
|
||||
//${VERDACCIO_URL#*://}/:_authToken=
|
||||
EOF
|
||||
PUBLISH_REGISTRY="$VERDACCIO_URL"
|
||||
PUBLISH_ARGS="--registry $VERDACCIO_URL --userconfig $NPM_RC"
|
||||
fi
|
||||
|
||||
published=0
|
||||
skipped=0
|
||||
@@ -83,36 +120,14 @@ for entry in "${LOCAL_PATCHES[@]}"; do
|
||||
fail " Patched tarball not found: $TARBALL"
|
||||
fi
|
||||
|
||||
# Check if already published
|
||||
ENCODED_NAME=$(echo "$pkg_name" | sed 's|/|%2F|g')
|
||||
CHECK_URL="${NEXUS_URL}/repository/npm-hosted/${ENCODED_NAME}/${pkg_version}"
|
||||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" "$CHECK_URL")
|
||||
if [ "$HTTP" = "200" ]; then
|
||||
warn " $pkg_name@$pkg_version already in Nexus, skipping"
|
||||
log " Publishing $tarball_name..."
|
||||
if npm publish "$TARBALL" $PUBLISH_ARGS --tag patched 2>&1 | grep -v "^npm notice"; then
|
||||
log " ${GREEN}Published${NC} $pkg_name@$pkg_version"
|
||||
((published++)) || true
|
||||
else
|
||||
warn " $pkg_name@$pkg_version already exists or publish failed, skipping"
|
||||
((skipped++)) || true
|
||||
continue
|
||||
fi
|
||||
|
||||
log " Publishing $tarball_name to Nexus..."
|
||||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" -X PUT \
|
||||
-u "$NEXUS_USER:$NEXUS_PASS" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary "@$TARBALL" \
|
||||
"${NEXUS_NPM_HOSTED}${pkg_name}/-/${tarball_name}")
|
||||
|
||||
case "$HTTP" in
|
||||
200|201)
|
||||
log " ${GREEN}Published${NC} $pkg_name@$pkg_version"
|
||||
((published++)) || true
|
||||
;;
|
||||
400)
|
||||
warn " $pkg_name@$pkg_version already exists (HTTP 400)"
|
||||
((skipped++)) || true
|
||||
;;
|
||||
*)
|
||||
fail " Failed to publish $pkg_name@$pkg_version (HTTP $HTTP)"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
for pkg_spec in "${PATCHES[@]}"; do
|
||||
@@ -122,42 +137,21 @@ for pkg_spec in "${PATCHES[@]}"; do
|
||||
log "Processing $pkg_name@$pkg_version..."
|
||||
|
||||
# Check if already published to Nexus
|
||||
CHECK_URL="${NEXUS_URL}/repository/npm-hosted/${pkg_name}/${pkg_version}"
|
||||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" "$CHECK_URL")
|
||||
if [ "$HTTP" = "200" ]; then
|
||||
warn " $pkg_name@$pkg_version already in Nexus, skipping"
|
||||
((skipped++)) || true
|
||||
continue
|
||||
fi
|
||||
|
||||
# Download the tarball from npmjs.org
|
||||
# Download from npmjs.org and publish to local registry
|
||||
cd "$WORK_DIR"
|
||||
TARBALL=$(npm pack "$pkg_spec" 2>/dev/null)
|
||||
if [ ! -f "$TARBALL" ]; then
|
||||
fail " Failed to download $pkg_spec"
|
||||
fi
|
||||
|
||||
# Publish to Nexus hosted repo
|
||||
log " Publishing $TARBALL to Nexus..."
|
||||
HTTP=$(curl -s -o /dev/null -w "%{http_code}" -X PUT \
|
||||
-u "$NEXUS_USER:$NEXUS_PASS" \
|
||||
-H "Content-Type: application/octet-stream" \
|
||||
--data-binary "@$TARBALL" \
|
||||
"${NEXUS_NPM_HOSTED}${pkg_name}/-/${TARBALL}")
|
||||
|
||||
case "$HTTP" in
|
||||
200|201)
|
||||
log " ${GREEN}Published${NC} $pkg_name@$pkg_version"
|
||||
((published++)) || true
|
||||
;;
|
||||
400)
|
||||
warn " $pkg_name@$pkg_version already exists (HTTP 400)"
|
||||
((skipped++)) || true
|
||||
;;
|
||||
*)
|
||||
fail " Failed to publish $pkg_name@$pkg_version (HTTP $HTTP)"
|
||||
;;
|
||||
esac
|
||||
log " Publishing $TARBALL..."
|
||||
if npm publish "$TARBALL" $PUBLISH_ARGS --tag patched 2>&1 | grep -v "^npm notice"; then
|
||||
log " ${GREEN}Published${NC} $pkg_name@$pkg_version"
|
||||
((published++)) || true
|
||||
else
|
||||
warn " $pkg_name@$pkg_version already exists or publish failed, skipping"
|
||||
((skipped++)) || true
|
||||
fi
|
||||
|
||||
rm -f "$TARBALL"
|
||||
done
|
||||
@@ -165,8 +159,8 @@ done
|
||||
echo ""
|
||||
log "Done. published=$published skipped=$skipped"
|
||||
echo ""
|
||||
log "To use patched packages, add to .npmrc:"
|
||||
log " registry=${NEXUS_URL}/repository/npm-group/"
|
||||
echo ""
|
||||
log "Or use scoped overrides in package.json:"
|
||||
log ' "overrides": { "minimatch": "10.2.4", "tar": "7.5.11", "@esbuild-kit/core-utils": "3.3.3-metabuilder.0" }'
|
||||
if $USE_NEXUS; then
|
||||
log "Nexus npm-group: ${NEXUS_URL}/repository/npm-group/"
|
||||
else
|
||||
log "Verdaccio registry: $VERDACCIO_URL"
|
||||
fi
|
||||
|
||||
31
deployment/verdaccio.yaml
Normal file
31
deployment/verdaccio.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
# Verdaccio configuration for local npm patch registry
|
||||
# Serves patched packages (e.g. @esbuild-kit/core-utils) and proxies everything
|
||||
# else to npmjs.org.
|
||||
#
|
||||
# Usage:
|
||||
# npx verdaccio --config deployment/verdaccio.yaml &
|
||||
# bash deployment/publish-npm-patches.sh --verdaccio
|
||||
# # .npmrc already points @esbuild-kit:registry to localhost:4873
|
||||
|
||||
storage: /tmp/verdaccio-storage
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
timeout: 60s
|
||||
max_fails: 3
|
||||
packages:
|
||||
'@esbuild-kit/*':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: npmjs
|
||||
'**':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: npmjs
|
||||
server:
|
||||
keepAliveTimeout: 60
|
||||
log:
|
||||
type: stdout
|
||||
format: pretty
|
||||
level: warn
|
||||
listen: 0.0.0.0:4873
|
||||
Reference in New Issue
Block a user