From 216d37616765517818ad2f8fd724b832a568b8e1 Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Tue, 18 Aug 2026 02:01:04 +0400 Subject: [PATCH] ci: publish packages via git release branches, drop registry dependency --- .github/workflows/release.yml | 115 ++++++++++++++++++++++++---------- README.md | 66 ++++++++++--------- 2 files changed, 120 insertions(+), 61 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 54dc145..bdcb1d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,18 +5,87 @@ on: branches: - main -# Requires two repo secrets: -# NPM_REGISTRY_URL - full URL of the Verdaccio registry, reachable FROM THE RUNNER. -# Not set yet: the registry currently listens on 127.0.0.1:4873 on -# the dev server and the firewall allows only 80/443/SSH, so no -# external runner can reach it. Until that is resolved this job -# will fail at the publish step by design, rather than silently -# skipping the release. See docs/PACKAGE-EXTRACTION.md in the -# marketplaces repo. -# NPM_TOKEN - publish token for that registry (npm login --registry=). +# Publishes each package by force-pushing its built output to a release branch +# (release/auth, release/payment) where the repo root IS the package. Consumers +# install straight over git: +# +# "@marketplaces/auth": "git+.git#release/auth" +# +# No npm registry, no NPM_TOKEN, no network reachability problem - the only +# credential needed is the checkout token this workflow already has. jobs: - release: + release-branches: + runs-on: ubuntu-latest + permissions: + contents: write + strategy: + matrix: + package: [auth, payment] + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build --workspace packages/${{ matrix.package }} + + - name: Publish to release/${{ matrix.package }} + run: | + set -euo pipefail + PKG=${{ matrix.package }} + BRANCH="release/$PKG" + VERSION=$(node -p "require('./packages/$PKG/package.json').version") + + STAGE=$(mktemp -d) + cp -r "packages/$PKG/dist" "$STAGE/dist" + node -e " + const p = require('./packages/$PKG/package.json'); + delete p.scripts; + delete p.devDependencies; + require('fs').writeFileSync('$STAGE/package.json', JSON.stringify(p, null, 2) + '\n'); + " + cat > "$STAGE/README.md" < /dev/null + find . -maxdepth 1 -not -name '.git' -not -name '.' -exec rm -rf {} + + cp -r "$STAGE/." . + + git add -A + if git diff --cached --quiet; then + echo "No change for $PKG, nothing to publish." + exit 0 + fi + git commit -q -m "release: @marketplaces/$PKG $VERSION (built from $GITHUB_SHA)" + git push -f origin "$BRANCH" + + version-pr: runs-on: ubuntu-latest permissions: contents: write @@ -36,31 +105,11 @@ jobs: - name: Install dependencies run: npm ci - - name: Build - run: npm run build - - - name: Test - run: npm test - - - name: Configure registry auth - run: | - if [ -z "${{ secrets.NPM_REGISTRY_URL }}" ] || [ -z "${{ secrets.NPM_TOKEN }}" ]; then - echo "NPM_REGISTRY_URL and/or NPM_TOKEN are not set on this repo." - echo "The registry is not reachable from CI yet - see the comment at the top of this file." - exit 1 - fi - REGISTRY="${{ secrets.NPM_REGISTRY_URL }}" - HOST_PATH="${REGISTRY#http://}" - HOST_PATH="${HOST_PATH#https://}" - { - echo "@marketplaces:registry=${REGISTRY}" - echo "//${HOST_PATH%/}/:_authToken=${{ secrets.NPM_TOKEN }}" - } >> .npmrc - - - name: Create release PR or publish + # Opens/updates a "Version Packages" PR when unreleased changesets exist. + # Merging that PR bumps versions on main, which re-runs release-branches above. + - name: Version PR uses: changesets/action@v1 with: version: npm run version - publish: npm run release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 232118b..8b47773 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,63 @@ # vitanovaPackages -Shared client packages consumed by `marketplaces` and other projects as npm dependencies. +Shared client packages consumed by `marketplaces` and other projects. -- `packages/auth` — `@marketplaces/auth`. Real implementation. Two independent mechanisms: `telegram/` (live QR/session auth for customer + admin) and `ed25519/` (challenge/response admin auth, backend not shipped yet). +- `packages/auth` — `@marketplaces/auth`. Real implementation. Two independent mechanisms: `telegram/` (live QR/session auth, customer + admin) and `ed25519/` (challenge/response admin auth, backend not shipped yet). - `packages/payment` — `@marketplaces/payment`. Scaffold only, no implementation yet. -Full consumer documentation lives in the `marketplaces` repo: `docs/PACKAGES-USAGE.md`. Rationale: `docs/context/adrs/ADR-0001-extract-auth-and-payment-into-shared-marketplaces-packages.md`. +Consumer documentation lives in the `marketplaces` repo: `docs/PACKAGES-USAGE.md`. Rationale: `docs/context/adrs/ADR-0001-extract-auth-and-payment-into-shared-marketplaces-packages.md`. + +## Installing (no registry, no token) + +Each package is published to a **release branch** where the repo root *is* the package, so npm can install it straight over git: + +```json +{ + "dependencies": { + "@marketplaces/auth": "git+https://sources.vitanova.network/sdarbinyan/vitanovaPackages.git#release/auth", + "@marketplaces/payment": "git+https://sources.vitanova.network/sdarbinyan/vitanovaPackages.git#release/payment" + } +} +``` + +No npm registry, no auth token, no SSH tunnel, no CI secret. Anonymous git read is all that's required — a fresh clone plus `npm install` works on any machine and any CI runner. + +`release/auth` and `release/payment` are **generated**. Never commit to them by hand; they are force-pushed on every release. ## Layout -npm workspaces monorepo. Each package builds standalone with `tsc` to `dist/`, which is the only thing published (`files: ["dist"]`). +npm workspaces monorepo. Each package builds standalone with `tsc` to `dist/`. ```bash npm ci -npm run build # builds all workspaces -npm test # runs all workspace tests +npm run build # all workspaces +npm test # all workspaces ``` -Angular and rxjs are `peerDependencies` — the consuming app supplies them, so there is exactly one copy of Angular at runtime. +Angular and rxjs are `peerDependencies`, so the consuming app supplies exactly one copy at runtime. ## Making a change 1. Edit under `packages//src`, export from `index.ts`. 2. `npx changeset` — pick the package and bump type, write one line. CI rejects PRs without one. -3. Open a PR. `ci.yml` builds, tests, and checks for the changeset. -4. On merge to `main`, `release.yml` opens a "Version Packages" PR. Merging *that* publishes. +3. Open a PR against `main`. `ci.yml` builds, tests, and verifies the changeset exists. +4. On merge, `release.yml` rebuilds and force-pushes the release branches, and opens a "Version Packages" PR if there are unreleased changesets. Merging that PR bumps versions and triggers another release. +5. In the consuming project, run `npm update @marketplaces/auth` (git deps track the branch tip, so pin to a tag or commit SHA instead of the branch if you need reproducible installs). -## Registry — read this before expecting CI to publish +### Pinning -Packages go to a **private Verdaccio registry running on the dev server** (`213.21.246.138`, Docker container `verdaccio`, storage `/srv/marketplaces/verdaccio/`), not npmjs. +Branch refs move. For reproducible builds, pin to a commit: -It currently listens on `127.0.0.1:4873` and the server firewall allows only 80/443/SSH — **so no CI runner can reach it.** `release.yml` fails loudly at the auth step rather than pretending to succeed. Resolving this needs one of: - -- a reverse proxy through the existing nginx (a server-config change, plus TLS — there is no certificate on that box yet), or -- opening the port (plain HTTP with credentials on it — not recommended), or -- moving to a hosted registry entirely. - -Until then, publish manually through an SSH tunnel: - -```bash -ssh -L 4873:127.0.0.1:4873 seto@213.21.246.138 +``` +git+https://sources.vitanova.network/sdarbinyan/vitanovaPackages.git# ``` -```bash -npm login --registry=http://127.0.0.1:4873/ --scope=@marketplaces -npm run build -cd packages/auth && npm publish --registry http://127.0.0.1:4873/ -``` +`marketplaces` currently tracks `#release/auth` (branch tip) — deliberate while the package churns, worth pinning once it stabilises. -Once reachable, set repo secrets `NPM_REGISTRY_URL` and `NPM_TOKEN` and CI takes over. +## Workflow syntax -`release.yml`/`ci.yml` use GitHub Actions syntax. Gitea/Forgejo Actions are compatible; other CI systems need translating (same steps: install, build, test, changesets). +`ci.yml` / `release.yml` are GitHub Actions. Gitea/Forgejo Actions are compatible. Other CI needs translating — the steps are just: install, build, test, force-push a branch. + +## A private npm registry also exists + +A Verdaccio instance runs on the dev server (`213.21.246.138:4873`, Docker container `verdaccio`, storage `/srv/marketplaces/verdaccio/`) and holds `@marketplaces/auth@0.1.0` and `@marketplaces/payment@0.1.0`. It is **not** the path anything uses today — it is only reachable from the server itself or through an SSH tunnel, which is exactly why the git-branch approach above exists. Keep it or delete it; nothing depends on it.