main
  1name: Publish
  2
  3on:
  4  workflow_dispatch:
  5  release:
  6    types: [created]
  7
  8permissions: {}
  9
 10env:
 11  npm_config_audit: false
 12  npm_config_fund: false
 13
 14jobs:
 15  build:
 16    runs-on: ubuntu-latest
 17    steps:
 18      - uses: actions/checkout@v5
 19        with:
 20          persist-credentials: false
 21      - uses: actions/setup-node@v5
 22        with:
 23          node-version: 24
 24          cache: 'npm'
 25      - name: Compare release tag with package.json
 26        if: github.event_name == 'release'
 27        run: |
 28          RELEASE_VERSION=${GITHUB_REF#refs/tags/}
 29          PKG_VERSION=$(node -p "require('./package.json').version")
 30
 31          echo "Release tag: $RELEASE_VERSION"
 32          echo "package.json: $PKG_VERSION"
 33
 34          [ "$RELEASE_VERSION" = "$PKG_VERSION" ] || { echo "❌ Mismatch"; exit 1; }
 35
 36      - run: npm ci
 37      - run: npm test
 38        env:
 39          FORCE_COLOR: 3
 40      - uses: actions/upload-artifact@v4
 41        with:
 42          name: build-${{ github.run_id }}
 43          path: |
 44            build
 45            jsr.json
 46            package.json
 47            package-lite.json
 48            package-main.json
 49          retention-days: 1
 50
 51  version:
 52    runs-on: ubuntu-latest
 53    outputs:
 54      v: ${{ steps.ref.outputs.ZX_VERSION }}
 55      lite: ${{ steps.ref.outputs.ZX_VERSION }}-lite
 56    steps:
 57      - uses: actions/checkout@v5
 58        with:
 59          persist-credentials: false
 60      - id: ref
 61        run: |
 62          echo SHA_SHORT=$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
 63          echo ZX_VERSION=$(jq -r '.version' package.json) >> $GITHUB_OUTPUT
 64
 65  npm-publish:
 66    needs: [build, version]
 67    runs-on: ubuntu-latest
 68    permissions:
 69      checks: read
 70      statuses: write
 71      contents: write
 72      packages: write
 73      id-token: write
 74    env:
 75      GOOGLE_NPM_REGISTRY: wombat-dressing-room.appspot.com
 76      GOOGLE_NPM_TOKEN: ${{ secrets.AUTH_TOKEN }}
 77      GH_NPM_REGISTRY: npm.pkg.github.com
 78      GH_NPM_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 79      ZX_VERSION: ${{ needs.version.outputs.v }}
 80    steps:
 81      - uses: actions/checkout@v5
 82        with:
 83          persist-credentials: false
 84      - uses: actions/setup-node@v5
 85        with:
 86          node-version: 24
 87          cache: 'npm'
 88      - name: Configure npmrc
 89        run: |
 90          echo "//${{ env.GOOGLE_NPM_REGISTRY }}/:_authToken=$GOOGLE_NPM_TOKEN" >> .npmrc
 91          echo "//${{ env.GH_NPM_REGISTRY }}/:_authToken=$GH_NPM_TOKEN" >> .npmrc
 92      - uses: actions/download-artifact@v5
 93        with:
 94          name: build-${{ github.run_id }}
 95
 96      - name: pushing to ${{ env.GOOGLE_NPM_REGISTRY }}
 97        run: |
 98          mv -f package-main.json package.json
 99          npm publish --provenance --access=public --registry https://${{ env.GOOGLE_NPM_REGISTRY }}
100
101      - name: pushing to ${{ env.GH_NPM_REGISTRY }}
102        run: |
103          cat <<< $(jq '.name="@${{ github.repository }}"' package.json) > package.json
104          npm publish --no-git-tag-version --access=public --registry https://${{ env.GH_NPM_REGISTRY }}
105
106      - name: pushing lite snapshot to ${{ env.GOOGLE_NPM_REGISTRY }}
107        run: |
108          mv -f package-lite.json package.json
109          npm publish --provenance --access=public --no-git-tag-version --tag lite --registry https://${{ env.GOOGLE_NPM_REGISTRY }}
110
111  jsr-publish:
112    needs: build
113    runs-on: ubuntu-latest
114    permissions:
115      contents: read
116      id-token: write
117    steps:
118      - uses: actions/checkout@v5
119        with:
120          persist-credentials: false
121      - uses: actions/setup-node@v5
122        with:
123          node-version: 24
124          cache: 'npm'
125      - uses: actions/download-artifact@v5
126        with:
127          name: build-${{ github.run_id }}
128      - name: pushing to jsr.io
129        run: npx jsr publish --allow-dirty
130
131  docker-publish:
132    needs: [build, version]
133    runs-on: ubuntu-latest
134    # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
135    env:
136      REGISTRY: ghcr.io
137      IMAGE_NAME: ${{ github.repository }}
138      ZX_VERSION: ${{ needs.version.outputs.v }}
139
140    permissions:
141      contents: read
142      packages: write
143      attestations: write
144      id-token: write
145    steps:
146      - name: Checkout repository
147        uses: actions/checkout@v5
148        with:
149          persist-credentials: false
150
151      - uses: actions/download-artifact@v5
152        with:
153          name: build-${{ github.run_id }}
154
155      - name: Log in to the Container registry
156        uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 #v3.4.0
157        with:
158          registry: ${{ env.REGISTRY }}
159          username: ${{ github.actor }}
160          password: ${{ secrets.GITHUB_TOKEN }}
161      - name: Extract metadata (tags, labels) for Docker
162        id: meta
163        uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 #v5.7.0
164        with:
165          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
166          tags: |
167            type=sha
168            type=semver,pattern={{version}},value=v${{ env.ZX_VERSION }}
169      - name: Build and push Docker image
170        id: push
171        uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 #v6.18.0
172        with:
173          context: ./
174          file: ./dcr/Dockerfile
175          push: true
176          tags: ${{ steps.meta.outputs.tags }}
177          labels: ${{ steps.meta.outputs.labels }}
178
179      - name: Generate artifact attestation
180        uses: actions/attest-build-provenance@v2
181        with:
182          subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
183          subject-digest: ${{ steps.push.outputs.digest }}
184          push-to-registry: true