ci: publish packages via git release branches, drop registry dependency
This commit is contained in:
115
.github/workflows/release.yml
vendored
115
.github/workflows/release.yml
vendored
@@ -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=<url>).
|
||||
# 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+<this repo>.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" <<EOF
|
||||
# @marketplaces/$PKG — release branch
|
||||
|
||||
**Generated branch. Do not edit by hand.** Built from \`main\` at $GITHUB_SHA.
|
||||
|
||||
Install:
|
||||
|
||||
\`\`\`
|
||||
git+${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git#$BRANCH
|
||||
\`\`\`
|
||||
|
||||
Source lives on \`main\` under \`packages/$PKG\`.
|
||||
EOF
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
git checkout --orphan "$BRANCH"
|
||||
git rm -rf --cached . > /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 }}
|
||||
|
||||
66
README.md
66
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/<name>/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#<commit-sha>
|
||||
```
|
||||
|
||||
```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.
|
||||
|
||||
Reference in New Issue
Block a user