@voxgig/sdkgen-infrapack 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -84,6 +84,17 @@ main: kit: target: 'seneca-provider': {
84
84
  # Windows alike. A knob that produces an uninstallable dependency is worse
85
85
  # than no knob.
86
86
  #
87
+ # NPM 12 REFUSES BOTH BY DEFAULT. `allow-git` and `allow-remote` default to
88
+ # "none", so a git or tarball dependency is rejected before anything is
89
+ # fetched (EALLOWGIT / EALLOWREMOTE). The generated CI passes the matching
90
+ # `--allow-*=all` for whichever kind is configured, because the project
91
+ # opting into what it declared is reasonable — but a CONSUMER of the
92
+ # published provider gets no such flag, and will hit the same wall.
93
+ #
94
+ # So this is a stopgap for an SDK that is not published YET, not a
95
+ # substitute for publishing it. An SDK on a registry needs none of it, and
96
+ # the default `npm` kind is the one that works everywhere.
97
+ #
87
98
  # `spec` states the whole dependency value outright and wins over
88
99
  # everything.
89
100
  sdk: dep: {
@@ -1699,7 +1699,7 @@ ${!provider.liveApp ? '' : `
1699
1699
  done
1700
1700
  echo "server did not start; live tests will skip"
1701
1701
  `}
1702
- - run: npm install
1702
+ - run: npm install${provider.sdkInstallFlag}
1703
1703
 
1704
1704
  # The Seneca host framework is a PEER dependency, so the test suite needs
1705
1705
  # it installed explicitly. --no-save keeps npm from rewriting the peer
@@ -1741,14 +1741,30 @@ ${!provider.liveApp ? '' : `
1741
1741
  # lets npm exchange a GitHub OIDC token for a short-lived publish credential,
1742
1742
  # and provenance is attached automatically.
1743
1743
  #
1744
+ # TWO JOBS, BECAUSE THEY NEED DIFFERENT PRIVILEGES.
1745
+ #
1746
+ # verify contents: read, and nothing else. Runs npm install, the build
1747
+ # and the tests — i.e. dependency lifecycle scripts and project
1748
+ # code. It holds no publish credential.
1749
+ # publish id-token: write, contents: read. Installs NO project
1750
+ # dependencies and runs NO project code: this package ships
1751
+ # \`dist\`, which is committed, so nothing needs building to pack.
1752
+ #
1753
+ # THE SPLIT IS THE POINT. A compromised dependency lifecycle script can ask
1754
+ # the runner for any OIDC token the JOB is permitted to mint, so a job that
1755
+ # both installs dependencies and holds \`id-token: write\` can be made to
1756
+ # publish as this package before its own gates finish. Keeping the install in
1757
+ # a job with no id-token, and the credential in a job that installs nothing,
1758
+ # is what makes the isolation real rather than nominal.
1759
+ #
1744
1760
  # The trusted publisher must be registered on npmjs.com for this package
1745
1761
  # against THIS filename (publish.yml); renaming this file breaks publishing
1746
1762
  # until the npm-side config is updated to match.
1747
1763
  #
1748
- # npm cannot publish a package's FIRST version this way — the settings page
1749
- # that configures a trusted publisher only exists once a version is there. So
1750
- # release ${provider.version} by hand once, configure the publisher, and every
1751
- # release after that is a tag push.
1764
+ # npm cannot configure a trusted publisher for a package that does not exist
1765
+ # yet — the settings page appears once a version is on the registry. So the
1766
+ # FIRST version of a new package is published by hand, once, with an
1767
+ # authenticated npm; every release after that is a tag push.
1752
1768
  #
1753
1769
  # Release flow: bump the version in the SDK model
1754
1770
  # (\`main: kit: target: 'seneca-provider': publish: version\`), regenerate,
@@ -1762,38 +1778,36 @@ on:
1762
1778
  workflow_dispatch:
1763
1779
 
1764
1780
  jobs:
1765
- publish:
1766
- name: npm publish
1781
+ verify:
1782
+ name: verify
1767
1783
  runs-on: ubuntu-latest
1768
1784
  timeout-minutes: 15
1785
+
1786
+ # Deliberately the default-minimum. This job runs third-party code.
1769
1787
  permissions:
1770
- id-token: write
1771
1788
  contents: read
1772
1789
 
1790
+ outputs:
1791
+ version: \${{ steps.version.outputs.version }}
1792
+
1773
1793
  steps:
1774
1794
  - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
1775
1795
 
1776
1796
  - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
1777
1797
  with:
1778
1798
  node-version: 24.x
1779
- registry-url: 'https://registry.npmjs.org'
1780
-
1781
- # Trusted publishing requires npm >= 11.5.1.
1782
- - name: Use a trusted-publishing capable npm
1783
- run: npm install -g npm@latest
1784
1799
 
1785
1800
  # install, not ci: this package does not commit a lockfile.
1786
- - run: npm install
1801
+ - run: npm install${provider.sdkInstallFlag}
1787
1802
 
1788
1803
  # The Seneca host framework is a PEER dependency, so the test suite
1789
1804
  # needs it installed explicitly.
1790
1805
  #
1791
1806
  # --no-save IS LOAD-BEARING. Without it npm rewrites the peer ranges in
1792
- # package.json to carets on whatever it resolved, and \`npm publish\`
1793
- # below then ships that rewritten manifest — so an authored \`>=26\`
1794
- # reaches consumers as \`^28.1.0\` and the package refuses to install for
1795
- # anyone on a newer major. The repo looks fine; only the artifact is
1796
- # narrowed. Install into node_modules, leave the manifest alone.
1807
+ # package.json to carets on whatever it resolved, and a later publish
1808
+ # ships that rewritten manifest — so an authored \`>=26\` reaches
1809
+ # consumers as \`^28.1.0\` and the package refuses to install for anyone
1810
+ # on a newer major. The repo looks fine; only the artifact is narrowed.
1797
1811
  - run: npm i --no-save seneca seneca-entity seneca-promisify @seneca/provider @seneca/env
1798
1812
 
1799
1813
  - run: npm run build
@@ -1802,15 +1816,75 @@ jobs:
1802
1816
  # The tag must match what the manifest declares, or a tag push silently
1803
1817
  # republishes whatever version happens to be in package.json.
1804
1818
  - name: Check the tag matches the manifest version
1819
+ id: version
1820
+ run: |
1821
+ set -euo pipefail
1822
+ PKG=\$(node -p "require('./package.json').version")
1823
+ if [ "\${GITHUB_REF_TYPE:-}" = "tag" ]; then
1824
+ TAG="\${GITHUB_REF_NAME#v}"
1825
+ if [ "\$TAG" != "\$PKG" ]; then
1826
+ echo "::error::tag v\$TAG does not match package.json \$PKG"
1827
+ exit 1
1828
+ fi
1829
+ fi
1830
+ echo "version=\$PKG" >> "\$GITHUB_OUTPUT"
1831
+
1832
+ # WHAT THE PUBLISH JOB WILL PACK, checked HERE where the code already
1833
+ # ran. That job builds nothing, so a missing or stale \`dist\` would
1834
+ # otherwise be discovered by consumers rather than by this workflow.
1835
+ - name: The committed dist matches the source
1805
1836
  run: |
1806
- TAG="\${GITHUB_REF_NAME#v}"
1807
- PKG=$(node -p "require('./package.json').version")
1808
- if [ "$TAG" != "$PKG" ]; then
1809
- echo "tag v$TAG does not match package.json $PKG"
1837
+ set -euo pipefail
1838
+ if ! git diff --quiet -- dist; then
1839
+ echo "::error::dist/ is not up to date with src/ -- rebuild and commit it"
1840
+ git diff --stat -- dist
1810
1841
  exit 1
1811
1842
  fi
1812
1843
 
1844
+ publish:
1845
+ name: npm publish
1846
+ needs: verify
1847
+ runs-on: ubuntu-latest
1848
+ timeout-minutes: 15
1849
+
1850
+ # The ONLY job holding the publish credential — and it installs no
1851
+ # project dependencies and runs no project code. See the header.
1852
+ permissions:
1853
+ id-token: write
1854
+ contents: read
1855
+
1856
+ steps:
1857
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
1858
+
1859
+ - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
1860
+ with:
1861
+ node-version: 24.x
1862
+ registry-url: 'https://registry.npmjs.org'
1863
+
1864
+ # Trusted publishing requires npm >= 11.5.1. This is npm itself, not a
1865
+ # project dependency: no package.json here is consulted.
1866
+ - name: Use a trusted-publishing capable npm
1867
+ run: npm install -g npm@latest
1868
+
1869
+ # THE REGISTRY IS THE SOURCE OF TRUTH FOR "IS THIS RELEASED", not the
1870
+ # tag. A re-run of a workflow that already published would otherwise
1871
+ # fail on a version conflict and report a red release that in fact
1872
+ # succeeded.
1873
+ - name: Is this version already on npm?
1874
+ id: registry
1875
+ env:
1876
+ VERSION: \${{ needs.verify.outputs.version }}
1877
+ run: |
1878
+ set -euo pipefail
1879
+ if npm view "${provider.pkgName}@\$VERSION" version >/dev/null 2>&1; then
1880
+ echo "published=true" >> "\$GITHUB_OUTPUT"
1881
+ echo "\$VERSION is already on npm — skipping publish"
1882
+ else
1883
+ echo "published=false" >> "\$GITHUB_OUTPUT"
1884
+ fi
1885
+
1813
1886
  - name: Publish to npm
1887
+ if: steps.registry.outputs.published == 'false'
1814
1888
  run: npm publish --access public
1815
1889
  `)
1816
1890
  })
@@ -723,6 +723,21 @@ const Main = cmp(function Main(props: any) {
723
723
  // CI note says so, because "npm install is all you need" stops being
724
724
  // true the moment git or a tarball URL is in the path.
725
725
  sdkGit: !sdkDep.startsWith('^'),
726
+ // THE OPT-IN A NON-REGISTRY DEPENDENCY NEEDS, or ''.
727
+ //
728
+ // npm 12 defaults `allow-git` and `allow-remote` to "none" and REFUSES
729
+ // such a dependency outright — EALLOWGIT / EALLOWREMOTE, before it
730
+ // fetches anything. Older npm allowed both, so a workflow that passes
731
+ // today fails the moment its runner image updates; this provider's own
732
+ // publish run failed that way within hours of the build run passing,
733
+ // because publishing upgrades npm first.
734
+ //
735
+ // Emitted ONLY where the project chose such a dependency: it is the
736
+ // project opting into what it already declared, not a default weakened
737
+ // for everyone. Publishing the SDK remains the durable answer, and this
738
+ // flag exists so an unpublished one is workable meanwhile.
739
+ sdkInstallFlag: sdkDep.startsWith('github:') ? ' --allow-git=all' :
740
+ (sdkDep.startsWith('http') ? ' --allow-remote=all' : ''),
726
741
  repoUrl: repo.url,
727
742
  // The SDK's own repo, for pointing at the companion test server which is
728
743
  // only distributed in source.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voxgig/sdkgen-infrapack",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "Infrastructure-provider targets for the Voxgig SDK Generator: Seneca provider.",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
@@ -3,7 +3,7 @@
3
3
  "package": 1
4
4
  },
5
5
  "name": "@voxgig/sdkgen-infrapack",
6
- "version": "0.0.7",
6
+ "version": "0.0.9",
7
7
  "engines": {
8
8
  "sdkgen": ">=4.12.0"
9
9
  },