Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
33e62fa
ci: switch to ubuntu-latest-large, likely root cause of stuck runs
abueide Jul 22, 2026
3704759
fix: bump curation-blocked dependencies (flatted, ip, lodash-es)
abueide Jul 22, 2026
5dad1b8
fix: bump remaining curation-blocked dependencies (batch of 16)
abueide Jul 22, 2026
342a937
fix: eliminate tar@6.2.1 via node-gyp bump, tighten yarn network time…
abueide Jul 22, 2026
7b28e67
revert: remove ineffective httpTimeout/httpRetry fail-fast attempt
abueide Jul 22, 2026
9a6569e
ci: add a curation audit step for clearer diagnostics than a raw 403
abueide Jul 22, 2026
e41f4fc
fix: add set -o pipefail so a failed yarn install is actually detected
abueide Jul 22, 2026
17305d2
refactor: run the curation audit pre-flight instead of after install …
abueide Jul 22, 2026
4181a44
fix: pass --legacy-peer-deps to the curation audit's npm resolution
abueide Jul 22, 2026
28d5e6a
fix: audit each resolved package in isolation instead of one combined…
abueide Jul 22, 2026
43c5f66
revert: audit reactively against yarn's own confirmed-blocked packages
abueide Jul 22, 2026
9c5f43d
fix: dedupe the curation extraction against yarn's repeated failure l…
abueide Jul 22, 2026
7d14f60
fix: resolve the actual curation-blocked transitive dependencies
abueide Jul 22, 2026
582ec55
fix: pin ws to exact known-good versions instead of floating carets
abueide Jul 22, 2026
5bfe3b9
fix: pin ws 7.x line to the CVE-patched 7.5.11, not 7.5.10
abueide Jul 22, 2026
9b3cf74
fix: install treefmt + shfmt in CI so format:check can actually run
abueide Jul 24, 2026
37a1b99
fix: drop the dead nix formatter from treefmt.toml
abueide Jul 24, 2026
2349614
fix: exclude .yarnrc.yml from prettier formatting checks
abueide Jul 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions .github/actions/curation-audit/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
name: 'Curation Audit'
description: 'On install failure, run a JFrog curation audit against just the packages yarn actually 403d, for a clear policy reason instead of a raw 403'

inputs:
install-log:
description: 'Path to the captured yarn install output'
required: true

runs:
using: 'composite'
steps:
- name: Extract 403d packages from the install log
shell: bash
id: extract
env:
INSTALL_LOG: ${{ inputs.install-log }}
run: |
set -euo pipefail
WORKDIR=$(mktemp -d)
echo "AUDIT_WORKDIR=$WORKDIR" >> "$GITHUB_ENV"

# yarn logs each curation 403 as three lines, and prints the same
# failure twice: once in the resolution tree (with a │/└ prefix) and
# once more in the final summary (no prefix) - the prefix is
# optional here so both forms normalize to the same name@version
# and collapse into one entry via sort -u below.
# ➤ YN0035: │ <name>@npm:<version>: The remote server failed to provide...
# ➤ YN0035: │ Response Code: 403 (Forbidden)
sed -E 's/\x1b\[[0-9;]*m//g' "$INSTALL_LOG" \
| grep "npm:.*: The remote server failed" \
| sed -E 's/.*YN0035: ([│└] )?//' \
| sed -E 's/(@npm:[^:]+): The remote.*/\1/' \
| sed -E 's/@npm:/@/' \
| sort -u > "$WORKDIR/packages.txt" || true

count=$(wc -l < "$WORKDIR/packages.txt" | tr -d ' ')
echo "count=$count" >> "$GITHUB_OUTPUT"
echo "Found $count curation-blocked package(s):"
cat "$WORKDIR/packages.txt"

host=$(echo "${ARTIFACTORY_URL}" | sed -E 's#https?://##')
cat > "$WORKDIR/base.npmrc" <<EOF
registry=${ARTIFACTORY_URL}/artifactory/api/npm/virtual-npm-thirdparty/
//${host}/artifactory/api/npm/virtual-npm-thirdparty/:_authToken=${YARN_NPM_AUTH_TOKEN}
EOF

cat > "$WORKDIR/check_one.sh" <<'SCRIPT'
#!/usr/bin/env bash
set -uo pipefail

pkg="$1"
name="${pkg%@*}"
version="${pkg##*@}"

tmpdir=$(mktemp -d)
cp "${AUDIT_WORKDIR}/base.npmrc" "$tmpdir/.npmrc"
python3 -c '
import json, sys
name, version, out = sys.argv[1], sys.argv[2], sys.argv[3]
json.dump({"name": "curation-audit-synthetic", "version": "1.0.0", "private": True, "dependencies": {name: version}}, open(out, "w"))
' "$name" "$version" "$tmpdir/package.json"

out=$(cd "$tmpdir" && jf ca --run-native --legacy-peer-deps --format=table 2>&1)
exit_status=$?
rm -rf "$tmpdir"

# jf's own exit code doesn't distinguish a real curation block from noise
# (e.g. npm ls ELSPROBLEMS when a package's own peer deps aren't declared
# in this single-package synthetic project) - only treat it as a real
# block when the output actually says so.
if echo "$out" | grep -qE "download blocking policy|Found [1-9][0-9]* blocked packages?"; then
echo "::group::BLOCKED: $pkg"
echo "$out"
echo "::endgroup::"
exit 1
elif [ $exit_status -ne 0 ]; then
echo "::group::Audit inconclusive for $pkg (non-curation resolution error, ignoring)"
echo "$out"
echo "::endgroup::"
fi
exit 0
SCRIPT
chmod +x "$WORKDIR/check_one.sh"

- name: Install jf CLI
if: steps.extract.outputs.count != '0'
shell: bash
run: |
curl -fkL https://getcli.jfrog.io/v2-jf | sh
sudo mv jf /usr/local/bin/jf

- name: Configure jf against the SDK build lane
if: steps.extract.outputs.count != '0'
shell: bash
run: |
jf c add curation-audit-server \
--url="${ARTIFACTORY_URL}" \
--access-token="${YARN_NPM_AUTH_TOKEN}" \
--interactive=false \
--overwrite
jf c use curation-audit-server

- name: Curation audit each blocked package
if: steps.extract.outputs.count != '0'
shell: bash
run: |
set -uo pipefail
xargs -P 8 -n 1 "${AUDIT_WORKDIR}/check_one.sh" < "${AUDIT_WORKDIR}/packages.txt"
exit_status=$?
if [ $exit_status -ne 0 ]; then
echo "::error::Curation blocked one or more packages - see the BLOCKED groups above for the policy reason on each."
exit 1
fi
27 changes: 23 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ env:
jobs:
ci:
name: Lint + Build + Test
runs-on: ubuntu-latest
runs-on: ubuntu-latest-large
permissions:
contents: read
id-token: write
Expand All @@ -29,9 +29,21 @@ jobs:
node-version: 22
- run: corepack enable
- name: Install dependencies
run: yarn install --immutable
run: |
set -o pipefail
yarn install --immutable 2>&1 | tee /tmp/yarn-install.log
- name: Curation Audit (on install failure)
if: failure()
uses: ./.github/actions/curation-audit
with:
install-log: /tmp/yarn-install.log
- name: Lint (eslint)
run: yarn lint
- name: Install treefmt + shfmt
run: |
curl -fsSL https://github.com/numtide/treefmt/releases/download/v2.5.0/treefmt_2.5.0_linux_amd64.tar.gz | sudo tar -xz -C /usr/local/bin treefmt
sudo curl -fsSL -o /usr/local/bin/shfmt https://github.com/mvdan/sh/releases/download/v3.13.1/shfmt_v3.13.1_linux_amd64
sudo chmod +x /usr/local/bin/shfmt
- name: Lint (formatting)
run: yarn format:check
- name: Build
Expand All @@ -44,7 +56,7 @@ jobs:
commitlint:
name: Commitlint
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
runs-on: ubuntu-latest-large
permissions:
contents: read
id-token: write
Expand All @@ -57,7 +69,14 @@ jobs:
node-version: 22
- run: corepack enable
- name: Install dependencies
run: yarn install --immutable
run: |
set -o pipefail
yarn install --immutable 2>&1 | tee /tmp/yarn-install.log
- name: Curation Audit (on install failure)
if: failure()
uses: ./.github/actions/curation-audit
with:
install-log: /tmp/yarn-install.log
- name: Validate PR title
run: echo "$PR_TITLE" | yarn commitlint
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
e2e-tests:
# Skip on fork PRs and Dependabot PRs where repo secrets aren't available
if: ${{ github.event_name != 'pull_request' || (github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]') }}
runs-on: ubuntu-latest
runs-on: ubuntu-latest-large

steps:
- name: Checkout SDK
Expand Down
55 changes: 47 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ env:
jobs:
ci:
name: Lint + Build + Test
runs-on: ubuntu-latest
runs-on: ubuntu-latest-large
permissions:
contents: read
id-token: write
Expand All @@ -35,9 +35,21 @@ jobs:
node-version: 22
- run: corepack enable
- name: Install dependencies
run: yarn install --immutable
run: |
set -o pipefail
yarn install --immutable 2>&1 | tee /tmp/yarn-install.log
- name: Curation Audit (on install failure)
if: failure()
uses: ./.github/actions/curation-audit
with:
install-log: /tmp/yarn-install.log
- name: Lint (eslint)
run: yarn lint
- name: Install treefmt + shfmt
run: |
curl -fsSL https://github.com/numtide/treefmt/releases/download/v2.5.0/treefmt_2.5.0_linux_amd64.tar.gz | sudo tar -xz -C /usr/local/bin treefmt
sudo curl -fsSL -o /usr/local/bin/shfmt https://github.com/mvdan/sh/releases/download/v3.13.1/shfmt_v3.13.1_linux_amd64
sudo chmod +x /usr/local/bin/shfmt
- name: Lint (formatting)
run: yarn format:check
- name: Build
Expand All @@ -51,7 +63,7 @@ jobs:
name: Release (dry-run)
if: inputs.type == 'dry-run'
needs: [ci]
runs-on: ubuntu-latest
runs-on: ubuntu-latest-large
permissions:
contents: write
issues: write
Expand All @@ -71,9 +83,18 @@ jobs:
node-version: 22
- run: corepack enable

- name: Install dependencies
run: |
set -o pipefail
yarn install --immutable 2>&1 | tee /tmp/yarn-install.log
- name: Curation Audit (on install failure)
if: failure()
uses: ./.github/actions/curation-audit
with:
install-log: /tmp/yarn-install.log

- name: Release (dry-run)
run: |
yarn install --immutable
yarn build
yarn multi-semantic-release --dry-run
env:
Expand All @@ -83,7 +104,7 @@ jobs:
name: Release (beta)
if: inputs.type == 'beta'
needs: [ci]
runs-on: ubuntu-latest
runs-on: ubuntu-latest-large
environment: Publish-Beta
permissions:
contents: write
Expand All @@ -104,9 +125,18 @@ jobs:
node-version: 22
- run: corepack enable

- name: Install dependencies
run: |
set -o pipefail
yarn install --immutable 2>&1 | tee /tmp/yarn-install.log
- name: Curation Audit (on install failure)
if: failure()
uses: ./.github/actions/curation-audit
with:
install-log: /tmp/yarn-install.log

- name: Release (beta)
run: |
yarn install --immutable
yarn build
yarn release
env:
Expand All @@ -118,7 +148,7 @@ jobs:
name: Release (production)
if: inputs.type == 'production'
needs: [ci]
runs-on: ubuntu-latest
runs-on: ubuntu-latest-large
environment: Publish
permissions:
contents: write
Expand All @@ -139,9 +169,18 @@ jobs:
node-version: 22
- run: corepack enable

- name: Install dependencies
run: |
set -o pipefail
yarn install --immutable 2>&1 | tee /tmp/yarn-install.log
- name: Curation Audit (on install failure)
if: failure()
uses: ./.github/actions/curation-audit
with:
install-log: /tmp/yarn-install.log

- name: Release (production)
run: |
yarn install --immutable
yarn build
yarn release
env:
Expand Down
44 changes: 43 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,47 @@
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
},
"packageManager": "yarn@4.1.0"
"packageManager": "yarn@4.1.0",
"resolutions": {
"flatted@^3.2.9": "^3.4.2",
"ip@^2.0.0": "^2.0.1",
"lodash-es@^4.17.21": "^4.18.0",
"@babel/plugin-transform-modules-systemjs@^7.23.9": "^7.29.4",
"@grpc/grpc-js@~1.9.0": "~1.9.16",
"diff@^5.1.0": "^5.2.2",
"fast-xml-parser@^4.0.12": "^4.5.5",
"glob@^10.2.2": "^10.5.0",
"glob@^10.3.10": "^10.5.0",
"glob@^10.3.7": "^10.5.0",
"image-size@^1.0.2": "^1.2.1",
"protobufjs@^7.2.5": "^7.6.5",
"shell-quote@1.8.0": "^1.9.0",
"shell-quote@^1.7.2": "^1.9.0",
"sigstore@^4.0.0": "^4.1.1",
"minimatch@^9.0.0": "^9.0.4",
"minimatch@^9.0.1": "^9.0.4",
"minimatch@^9.0.3": "^9.0.4",
"@semantic-release/npm@npm:^11.0.0": "^13.1.5",
"npm@^10.0.0": "10.9.0",
"npm@^11.6.2": "11.18.0",
"pacote@^17.0.0": "^17.0.7",
"pacote@^17.0.4": "^17.0.7",
"pacote@^17.0.6": "^17.0.7",
"pacote@^21.0.0": "^21.4.1",
"pacote@^21.0.2": "^21.4.1",
"pacote@^21.4.0": "^21.4.1",
"sigstore@^2.2.0": "^2.2.1",
"ws@^6.2.2": "6.2.4",
"ws@^7": "7.5.11",
"ws@^7.0.0": "7.5.11",
"ws@^7.5.1": "7.5.11",
"undici@^6.23.0": "^6.27.0",
"node-gyp@^12.4.0": "^13.0.1",
"node-gyp@latest": "^13.0.1",
"browserslist@^4.20.4": "^4.24.0",
"browserslist@^4.22.2": "^4.24.0",
"tar": "7.5.20",
"baseline-browser-mapping": "2.10.43",
"electron-to-chromium": "1.5.393"
}
}
8 changes: 4 additions & 4 deletions treefmt.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[formatter.nix]
command = "nixfmt"
includes = ["*.nix"]

[formatter.prettier]
command = "prettier"
options = ["--write"]
includes = ["*.js", "*.jsx", "*.ts", "*.tsx", "*.md", "*.yml", "*.yaml", "*.json"]
# .yarnrc.yml gets an auth block appended at CI runtime (Artifactory OIDC Auth
# step, before this check runs) - that injected content isn't prettier-
# formatted and shouldn't be, so don't flag it as a real formatting diff.
excludes = [".yarnrc.yml"]

[formatter.shfmt]
command = "shfmt"
Expand Down
Loading
Loading