diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml new file mode 100644 index 0000000..f784cb8 --- /dev/null +++ b/.github/workflows/release-npm.yml @@ -0,0 +1,64 @@ +name: Release npm + +# Publish @hashlock-tech/sdk. Trigger: a package-scoped tag, e.g. `typescript-v1.0.0`. +# git tag typescript-v1.0.0 && git push origin typescript-v1.0.0 +# Build runs WITHOUT OIDC; only the minimal `publish` job holds `id-token: write` and never runs +# untrusted install/build scripts. Uses OIDC Trusted Publishing (no long-lived token in the repo) — +# configure the npm trusted publisher once against THIS workflow file (release-npm.yml). +on: + push: + tags: ['typescript-v*'] + +permissions: + contents: read + +jobs: + build: + name: Build (no OIDC) + runs-on: ubuntu-latest + defaults: + run: + working-directory: typescript + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + node-version: 22 + - name: Verify tag matches package.json version + run: | + TAG="${GITHUB_REF_NAME#typescript-v}" + PKG="$(node -p "require('./package.json').version")" + echo "tag=$TAG package.json=$PKG" + [ "$TAG" = "$PKG" ] || { echo "::error::tag $GITHUB_REF_NAME does not match package.json version $PKG"; exit 1; } + - run: npm install + - run: npm run build + - run: npm pack # → typescript/*.tgz (built artifact to publish) + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: npm-package + path: typescript/*.tgz + if-no-files-found: error + + publish: + name: Publish to npm (OIDC) + needs: build + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # OIDC → npm trusted publishing + provenance + steps: + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: npm-package + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + with: + # Pinned Node whose BUNDLED npm (11.16.0) already satisfies OIDC trusted publishing (>= 11.5.1), + # so the privileged job runs no registry-supplied `npm install -g` in the OIDC context. + node-version: 24.18.0 + registry-url: https://registry.npmjs.org + # Publish the prebuilt tarball only — the OIDC job runs no untrusted install/build scripts. + - run: npm publish *.tgz --provenance --access public + # Trusted publisher configured → no NODE_AUTH_TOKEN needed. + # Token fallback: set env NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} and drop --provenance. diff --git a/.github/workflows/release-pypi.yml b/.github/workflows/release-pypi.yml new file mode 100644 index 0000000..5b3d63c --- /dev/null +++ b/.github/workflows/release-pypi.yml @@ -0,0 +1,58 @@ +name: Release PyPI + +# Publish hashlock-sdk. Trigger: a package-scoped tag, e.g. `python-v1.0.0`. +# git tag python-v1.0.0 && git push origin python-v1.0.0 +# Build runs WITHOUT OIDC; only the minimal `publish` job holds `id-token: write` and does nothing but +# publish the prebuilt distributions. Uses OIDC Trusted Publishing (no long-lived token in the repo) — +# configure the PyPI trusted publisher once against THIS workflow file (release-pypi.yml). +on: + push: + tags: ['python-v*'] + +permissions: + contents: read + +jobs: + build: + name: Build (no OIDC) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 + with: + persist-credentials: false + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 + with: + python-version: '3.11' + - name: Verify tag matches pyproject version + working-directory: python + run: | + TAG="${GITHUB_REF_NAME#python-v}" + PKG="$(grep -E '^version = ' pyproject.toml | head -1 | cut -d'"' -f2)" + echo "tag=$TAG pyproject=$PKG" + [ "$TAG" = "$PKG" ] || { echo "::error::tag $GITHUB_REF_NAME does not match pyproject version $PKG"; exit 1; } + - run: pip install build + - run: python -m build + working-directory: python + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: pypi-dist + path: python/dist/* + if-no-files-found: error + + publish: + name: Publish to PyPI (OIDC) + needs: build + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write # OIDC → PyPI trusted publishing + steps: + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: pypi-dist + path: dist + - uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # release/v1 + with: + packages-dir: dist + # Trusted publisher configured → no token needed. + # Token fallback: add `password: ${{ secrets.PYPI_TOKEN }}`.