mirror of
https://github.com/danielsogl/awesome-cordova-plugins.git
synced 2026-08-04 00:00:08 +08:00
ci: publish to npm via trusted publishing (OIDC)
npm validates the OIDC claim of the entry-point workflow, not the one that runs `npm publish`. Calling publish.yml via workflow_call meant the trust check could never match, so the publish job moves inline into release-please.yml and publish.yml is removed. setup-node with Node 22 ships npm 10.x; trusted publishing needs >= 11.5.1, hence the explicit npm upgrade before publishing. NPM_TOKEN stays as a fallback for packages that have no trusted publisher yet — a brand new plugin cannot get one until it exists on npm. OIDC takes precedence wherever a config is present. Adds scripts/tasks/trust-packages.sh to configure the trusted publisher for all 258 packages; npm has no multi-package call and `npm trust` requires interactive 2FA, so it runs locally, in parallel, and is resumable.
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
name: Publish to npm
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.3.1
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
registry-url: https://registry.npmjs.org
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
run: npm run lint -- --quiet
|
||||
|
||||
- name: Test
|
||||
run: npm test
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Publish to npm
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npm run npmpub
|
||||
@@ -27,8 +27,45 @@ jobs:
|
||||
config-file: release-please-config.json
|
||||
manifest-file: .release-please-manifest.json
|
||||
|
||||
# npm trusted publishing validates the OIDC claim of the *entry point* workflow,
|
||||
# not the one that runs `npm publish`. Keep this job inline — a reusable workflow
|
||||
# here breaks the trust check. See https://github.com/npm/documentation/issues/1755
|
||||
publish:
|
||||
needs: release-please
|
||||
if: ${{ needs.release-please.outputs.release_created }}
|
||||
uses: ./.github/workflows/publish.yml
|
||||
secrets: inherit
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4.3.1
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4.4.0
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
registry-url: https://registry.npmjs.org
|
||||
|
||||
# node 22 ships npm 10.x; trusted publishing (OIDC) requires npm >= 11.5.1
|
||||
- name: Update npm
|
||||
run: npm install -g npm@latest
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Lint
|
||||
run: npm run lint -- --quiet
|
||||
|
||||
- name: Test
|
||||
run: npm test
|
||||
|
||||
- name: Build
|
||||
run: npm run build
|
||||
|
||||
- name: Publish to npm
|
||||
env:
|
||||
# fallback for packages without a trusted publisher yet (e.g. brand new plugins).
|
||||
# OIDC takes precedence whenever the package has one configured.
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
run: npm run npmpub
|
||||
|
||||
@@ -7,3 +7,5 @@ src/@awesome-cordova-plugins/plugins/**/ngx
|
||||
*.d.ts
|
||||
injectable-classes.json
|
||||
|
||||
# npm trust bulk setup progress
|
||||
.npm-trust-done
|
||||
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env bash
|
||||
# One-time (and after adding new plugins) bulk setup of npm trusted publishers.
|
||||
# Run locally after `npm login` — `npm trust` needs interactive 2FA and cannot run in CI.
|
||||
#
|
||||
# ./scripts/tasks/trust-packages.sh # 4 parallel workers
|
||||
# JOBS=8 ./scripts/tasks/trust-packages.sh # more, at the risk of rate limiting
|
||||
#
|
||||
# npm has no multi-package call, so this loops. The first package runs on its own to
|
||||
# trigger the browser 2FA prompt — tick "skip 2FA for the next 5 minutes" there. That
|
||||
# window is server-side, so the parallel batch afterwards runs unattended inside it.
|
||||
# Parallelism is what keeps the whole set inside a single window instead of ~4.
|
||||
#
|
||||
# A trust call is ~2s, so JOBS=4 is ~2 req/s — 4x npm's serial guidance, and the
|
||||
# reason there is no extra sleep here. If npm rate-limits, the affected packages
|
||||
# just land in the failed list and the next run picks them up.
|
||||
#
|
||||
# Packages that already have a trust config come back as E409 — npm only ever creates,
|
||||
# there is no update path — so those are treated as done. To actually *change* a config,
|
||||
# revoke it first: npm trust list <pkg> && npm trust revoke <pkg> --id=<id>, then re-run.
|
||||
#
|
||||
# Progress is recorded in .npm-trust-done; re-running resumes where it stopped.
|
||||
# Packages must already exist on npm; a brand new plugin publishes via NPM_TOKEN
|
||||
# on its first release, then gets its trust config here.
|
||||
set -euo pipefail
|
||||
|
||||
REPO=danielsogl/awesome-cordova-plugins
|
||||
WORKFLOW=release-please.yml
|
||||
JOBS="${JOBS:-4}"
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
SELF="$ROOT/scripts/tasks/trust-packages.sh"
|
||||
DONE="$ROOT/.npm-trust-done"
|
||||
|
||||
create() {
|
||||
npm trust github "$1" --file "$WORKFLOW" --repo "$REPO" --allow-publish --yes
|
||||
}
|
||||
|
||||
trust_one() {
|
||||
local pkg="$1" err rc=0
|
||||
err=$(mktemp)
|
||||
# stderr is buffered so E409 can be detected; stdout flows through untouched,
|
||||
# otherwise npm's "Press ENTER to open in the browser" prompt would be invisible
|
||||
create "$pkg" 2>"$err" || rc=$?
|
||||
|
||||
if [ "$rc" -eq 0 ]; then
|
||||
# single short line + O_APPEND is atomic, so parallel workers can't interleave
|
||||
echo "$pkg" >> "$DONE"
|
||||
elif grep -q "E409" "$err"; then
|
||||
# already has a trust config; npm only ever creates, so this is a no-op, not a failure
|
||||
echo ">> $pkg already configured, skipping" >&2
|
||||
echo "$pkg" >> "$DONE"
|
||||
rc=0
|
||||
else
|
||||
cat "$err" >&2
|
||||
fi
|
||||
|
||||
rm -f "$err"
|
||||
return "$rc"
|
||||
}
|
||||
|
||||
# re-entry point for xargs workers
|
||||
if [ "${1:-}" = "--one" ]; then
|
||||
trust_one "$2"
|
||||
exit
|
||||
fi
|
||||
|
||||
packages=(core)
|
||||
for dir in "$ROOT"/src/@awesome-cordova-plugins/plugins/*/; do
|
||||
packages+=("$(basename "$dir")")
|
||||
done
|
||||
|
||||
touch "$DONE"
|
||||
todo=()
|
||||
for name in "${packages[@]}"; do
|
||||
pkg="@awesome-cordova-plugins/$name"
|
||||
grep -qxF "$pkg" "$DONE" || todo+=("$pkg")
|
||||
done
|
||||
|
||||
if [ ${#todo[@]} -eq 0 ]; then
|
||||
echo "All ${#packages[@]} packages already configured."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "${#todo[@]} of ${#packages[@]} packages left for $REPO/.github/workflows/$WORKFLOW"
|
||||
echo
|
||||
echo ">> ${todo[0]} runs first. Approve in the browser and tick"
|
||||
echo ">> \"skip 2FA for the next 5 minutes\" — the rest then runs unattended."
|
||||
echo
|
||||
trust_one "${todo[0]}" || true
|
||||
|
||||
if [ ${#todo[@]} -gt 1 ]; then
|
||||
echo
|
||||
echo "Configuring the remaining $((${#todo[@]} - 1)) with $JOBS parallel workers..."
|
||||
printf '%s\n' "${todo[@]:1}" | xargs -P "$JOBS" -n1 "$SELF" --one || true
|
||||
fi
|
||||
|
||||
failed=()
|
||||
for pkg in "${todo[@]}"; do
|
||||
grep -qxF "$pkg" "$DONE" || failed+=("$pkg")
|
||||
done
|
||||
|
||||
if [ ${#failed[@]} -gt 0 ]; then
|
||||
echo
|
||||
printf 'failed: %s\n' "${failed[@]}"
|
||||
echo
|
||||
echo "An expired 2FA window is the usual cause — re-run and approve again."
|
||||
echo "Re-run retries only the failures; successes are recorded in $DONE."
|
||||
exit 1
|
||||
fi
|
||||
echo "Done."
|
||||
Reference in New Issue
Block a user