Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
69 changes: 52 additions & 17 deletions .github/workflows/publish-viewers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,58 @@ on:
push:
tags: ["viewer-v*"]
workflow_dispatch:
inputs:
release_tag:
description: Existing viewer-v* tag to retry with the current workflow
required: false
type: string

permissions:
contents: read

concurrency:
group: viewer-release-${{ github.ref }}
group: viewer-release-${{ inputs.release_tag || github.ref_name }}
cancel-in-progress: false

jobs:
verify:
outputs:
release_tag: ${{ steps.release-context.outputs.release_tag }}
release_version: ${{ steps.release-context.outputs.release_version }}
runs-on: ubuntu-latest
steps:
- name: Check out the tagged source without credentials
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
ref: ${{ inputs.release_tag || github.ref }}
- name: Validate the release context
id: release-context
env:
REQUESTED_TAG: ${{ inputs.release_tag }}
run: |
release_tag=""
if test -n "$REQUESTED_TAG"; then
release_tag="$REQUESTED_TAG"
elif test "$GITHUB_REF_TYPE" = tag; then
release_tag="$GITHUB_REF_NAME"
fi

if test -n "$release_tag"; then
if [[ ! "$release_tag" =~ ^viewer-v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z][0-9A-Za-z.-]*)?$ ]]; then
echo "Invalid viewer release tag: $release_tag" >&2
exit 1
fi
tag_commit="$(git rev-parse "refs/tags/$release_tag^{commit}")"
head_commit="$(git rev-parse 'HEAD^{commit}')"
if test "$tag_commit" != "$head_commit"; then
echo "Checked-out commit $head_commit does not match $release_tag ($tag_commit)." >&2
exit 1
fi
fi

echo "release_tag=$release_tag" >> "$GITHUB_OUTPUT"
echo "release_version=${release_tag#viewer-v}" >> "$GITHUB_OUTPUT"
- uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4.0.0
with:
version: 11.9.0
Expand All @@ -41,12 +77,10 @@ jobs:
- run: pnpm run closure:platform
- run: pnpm audit --prod --audit-level high
- name: Pack the exact verified release artifacts
env:
RELEASE_VERSION: ${{ steps.release-context.outputs.release_version }}
run: |
expected=""
if test "$GITHUB_REF_TYPE" = tag; then
expected="${GITHUB_REF_NAME#viewer-v}"
fi
node scripts/pack-viewer-release.mjs release-artifacts "$expected"
node scripts/pack-viewer-release.mjs release-artifacts "$RELEASE_VERSION"
- name: Upload verified release artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.0
with:
Expand All @@ -56,7 +90,7 @@ jobs:
retention-days: 1

release:
if: github.ref_type == 'tag'
if: needs.verify.outputs.release_tag != ''
needs: verify
runs-on: ubuntu-latest
permissions:
Expand All @@ -67,6 +101,9 @@ jobs:
with:
node-version: 24
registry-url: https://registry.npmjs.org
package-manager-cache: false
- name: Install an npm CLI with trusted publishing support
run: npm install --global npm@12.0.2
- name: Download the verified artifacts from this workflow run
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.0
with:
Expand All @@ -77,33 +114,31 @@ jobs:
run: sha256sum --check SHA256SUMS
- name: Verify existing packages and publish only missing artifacts
working-directory: release-artifacts
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: true
run: |
while IFS=$'\t' read -r name version tarball; do
if npm view "$name@$version" version >/dev/null 2>&1; then
node verify-registry-package.mjs "$tarball" "$name@$version"
else
dist_tag="latest"
case "$version" in *-*) dist_tag="next" ;; esac
npm publish "$tarball" --access public --provenance --tag "$dist_tag"
npm publish "$tarball" --access public --tag "$dist_tag"
fi
done < <(node -e 'const {packages}=require("./packages.json"); for (const item of packages) console.log([item.name,item.version,item.tarball].join("\t"))')
- name: Create GitHub release metadata
env:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.verify.outputs.release_tag }}
RELEASE_VERSION: ${{ needs.verify.outputs.release_version }}
run: |
version="${GITHUB_REF_NAME#viewer-v}"
prerelease=""
case "$version" in *-*) prerelease="--prerelease" ;; esac
if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "GitHub release $GITHUB_REF_NAME already exists."
case "$RELEASE_VERSION" in *-*) prerelease="--prerelease" ;; esac
if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "GitHub release $RELEASE_TAG already exists."
else
gh release create "$GITHUB_REF_NAME" release-artifacts/*.tgz release-artifacts/SHA256SUMS \
gh release create "$RELEASE_TAG" release-artifacts/*.tgz release-artifacts/SHA256SUMS \
--repo "$GITHUB_REPOSITORY" \
--verify-tag \
--title "AnyDoc viewer platform $version" \
--title "AnyDoc viewer platform $RELEASE_VERSION" \
--generate-notes \
$prerelease
fi
17 changes: 16 additions & 1 deletion docs/VIEWER_PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,22 @@ git push origin viewer-v0.1.0-alpha.14
The `Publish viewer platform` workflow verifies that every package manifest
matches the tag, uploads the exact verified tarballs, publishes only missing
packages, verifies any already-published artifacts, and creates the GitHub
release. Alpha versions publish under the npm `next` dist-tag.
release. Alpha versions publish under the npm `next` dist-tag. npm uses OpenID
Connect (OIDC) to authorize this workflow for each package, so the workflow does
not store or use an npm publishing token. npm creates provenance attestations
automatically.

If a release fails after its tag exists, retry that immutable tag with the
current workflow definition:

```sh
gh workflow run publish-viewers.yml --ref main \
-f release_tag=viewer-v0.1.0-alpha.14
```

The retry checks out the tag, confirms that `HEAD` is the tag commit, and runs
the same verification and publication gates. Do not move or replace a release
tag to retry a failed workflow.

Do not use Changesets to version the `@firecrawl/anydoc` binding packages. Their
cross-language `v*` workflow and version gate remain separate.
Loading