Skip to content
Draft
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
4 changes: 4 additions & 0 deletions .github/actions/comment-release-links/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ runs:
MARKER='design-system-release-summary'
LINKS_VALUE='npm design-system|https://www.npmjs.com/package/@comfyorg/design-system/v/{{version}}'
;;
packages/shared-frontend-utils/package.json)
MARKER='shared-frontend-utils-release-summary'
LINKS_VALUE='npm shared-frontend-utils|https://www.npmjs.com/package/@comfyorg/shared-frontend-utils/v/{{version}}'
;;
esac

DIFF_PREFIX='v'
Expand Down
98 changes: 98 additions & 0 deletions .github/workflows/ci-shared-frontend-utils-pack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
name: 'CI: Shared Frontend Utils Pack Check'

on:
pull_request:
branches-ignore: [wip/*, draft/*, temp/*]
paths:
- 'packages/shared-frontend-utils/**'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
verify-pack-contents:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Setup frontend
uses: ./.github/actions/setup-frontend

- name: Typecheck
run: pnpm -C packages/shared-frontend-utils typecheck

- name: Build package
run: pnpm -C packages/shared-frontend-utils build

- name: Verify packed tarball only contains compiled dist output
shell: bash
run: |
set -euo pipefail
UNEXPECTED=$(
pnpm -C packages/shared-frontend-utils pack --dry-run --json |
jq -r '
.files[].path
| select(
. != "package.json"
and . != "LICENSE"
and . != "README.md"
and (startswith("dist/") | not)
)
'
)
if [ -n "$UNEXPECTED" ]; then
echo "::error title=Unexpected files in tarball::Packed tarball contains files outside dist:" >&2
echo "$UNEXPECTED" >&2
exit 1
fi
echo 'Packed tarball contains only expected files.'

- name: Verify published manifest resolves to dist and pins real versions
shell: bash
run: |
set -euo pipefail
PACK_DIR="$RUNNER_TEMP/shared-frontend-utils-pack"
rm -rf "$PACK_DIR"
mkdir -p "$PACK_DIR"
pnpm -C packages/shared-frontend-utils pack --pack-destination "$PACK_DIR"
TARBALL=$(find "$PACK_DIR" -maxdepth 1 -name '*.tgz' | head -n 1)
if [ -z "$TARBALL" ]; then
echo "::error title=Pack failed::No tarball produced in $PACK_DIR" >&2
exit 1
fi
MANIFEST=$(tar -xzOf "$TARBALL" package/package.json)
NON_DIST_EXPORTS=$(
printf '%s' "$MANIFEST" |
jq -r '
[
.exports
| ..
| strings
| select(. != "./package.json" and (startswith("./dist/") | not))
]
| join(", ")
'
)
if [ -n "$NON_DIST_EXPORTS" ]; then
echo "::error title=Exports escape dist::Published exports must resolve to compiled dist output, got: $NON_DIST_EXPORTS" >&2
exit 1
fi
UNRESOLVED=$(
printf '%s' "$MANIFEST" |
jq -r '
(.dependencies // {}) + (.peerDependencies // {})
| to_entries[]
| select(.value | test("^(catalog:|workspace:)"))
| "\(.key)@\(.value)"
'
)
if [ -n "$UNRESOLVED" ]; then
echo "::error title=Unresolved workspace specifiers::Published manifest must not contain catalog:/workspace: ranges:" >&2
echo "$UNRESOLVED" >&2
exit 1
fi
echo 'Published manifest resolves to dist with real dependency ranges.'
84 changes: 84 additions & 0 deletions .github/workflows/publish-shared-frontend-utils-on-merge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Publish Shared Frontend Utils on PR Merge

on:
pull_request:
types: ['closed']
branches: [main, core/*]
paths:
- 'packages/shared-frontend-utils/package.json'

jobs:
resolve:
name: Resolve Version and Dist Tag
runs-on: ubuntu-latest
if: >
github.event.pull_request.merged == true &&
contains(github.event.pull_request.labels.*.name, 'Release')
outputs:
version: ${{ steps.get_version.outputs.version }}
dist_tag: ${{ steps.dist.outputs.dist_tag }}
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
persist-credentials: false

- name: Read shared-frontend-utils version
id: get_version
shell: bash
run: |
set -euo pipefail
VERSION=$(jq -r '.version' packages/shared-frontend-utils/package.json)
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Determine dist-tag
id: dist
env:
VERSION: ${{ steps.get_version.outputs.version }}
shell: bash
run: |
set -euo pipefail
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+- ]]; then
echo "dist_tag=next" >> "$GITHUB_OUTPUT"
else
echo "dist_tag=latest" >> "$GITHUB_OUTPUT"
fi

publish:
name: Publish Shared Frontend Utils to npm
needs: resolve
permissions:
contents: read
id-token: write
uses: ./.github/workflows/publish-shared-frontend-utils.yaml
with:
version: ${{ needs.resolve.outputs.version }}
dist_tag: ${{ needs.resolve.outputs.dist_tag }}
ref: ${{ github.event.pull_request.merge_commit_sha }}
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

comment_shared_frontend_utils_publish:
name: Comment Shared Frontend Utils Publish Summary
needs:
- resolve
- publish
if: success()
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Checkout merge commit
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.merge_commit_sha }}
fetch-depth: 2

- name: Post shared-frontend-utils release summary comment
uses: ./.github/actions/comment-release-links
with:
issue-number: ${{ github.event.pull_request.number }}
version_file: packages/shared-frontend-utils/package.json
154 changes: 154 additions & 0 deletions .github/workflows/publish-shared-frontend-utils.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: Publish Shared Frontend Utils

on:
workflow_dispatch:
inputs:
version:
description: 'Version to publish (e.g., 1.0.1)'
required: true
type: string
dist_tag:
description: 'npm dist-tag to use'
required: true
default: latest
type: string
ref:
description: 'Git ref to checkout (commit SHA, tag, or branch)'
required: false
type: string
workflow_call:
inputs:
version:
required: true
type: string
dist_tag:
required: false
type: string
default: latest
ref:
required: false
type: string
secrets:
NPM_TOKEN:
required: true

concurrency:
group: publish-shared-frontend-utils-${{ inputs.version }}
cancel-in-progress: false

jobs:
publish_shared_frontend_utils:
name: Publish @comfyorg/shared-frontend-utils
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- name: Determine ref to checkout
id: resolve_ref
env:
REF: ${{ inputs.ref }}
DEFAULT_REF: ${{ github.ref_name }}
shell: bash
run: |
set -euo pipefail
if [ -z "$REF" ]; then
REF="$DEFAULT_REF"
fi
if ! git check-ref-format --allow-onelevel "$REF"; then
echo "::error title=Invalid ref::Ref '$REF' fails git check-ref-format validation." >&2
exit 1
fi
echo "ref=$REF" >> "$GITHUB_OUTPUT"

- name: Checkout repository
uses: actions/checkout@v6
with:
ref: ${{ steps.resolve_ref.outputs.ref }}
fetch-depth: 1
persist-credentials: false

- name: Install pnpm
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v4.4.0

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: '.nvmrc'
cache: 'pnpm'
registry-url: https://registry.npmjs.org

- name: Install dependencies
run: pnpm install --frozen-lockfile --ignore-scripts
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1'

- name: Validate dist-tag
env:
DIST_TAG: ${{ inputs.dist_tag }}
shell: bash
run: |
set -euo pipefail
if [ -z "$DIST_TAG" ]; then
echo "::error title=Invalid dist-tag::dist_tag must not be empty" >&2
exit 1
fi
if ! node -e "process.exit(require('semver').validRange(process.argv[1]) ? 1 : 0)" "$DIST_TAG"; then
echo "::error title=Invalid dist-tag::Tag '$DIST_TAG' must not parse as a valid SemVer version or range (npm rejects such tags)" >&2
exit 1
fi

- name: Verify package
id: pkg
env:
INPUT_VERSION: ${{ inputs.version }}
shell: bash
run: |
set -euo pipefail
PACKAGE_JSON=packages/shared-frontend-utils/package.json
NAME=$(jq -r '.name' "$PACKAGE_JSON")
VERSION=$(jq -r '.version' "$PACKAGE_JSON")
if [ "$NAME" != "@comfyorg/shared-frontend-utils" ]; then
echo "::error title=Package name mismatch::${PACKAGE_JSON} name '$NAME' is not '@comfyorg/shared-frontend-utils'" >&2
exit 1
fi
if [ "$VERSION" != "$INPUT_VERSION" ]; then
echo "::error title=Version mismatch::${PACKAGE_JSON} version $VERSION does not match input $INPUT_VERSION" >&2
exit 1
fi
echo "name=$NAME" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Check if version already on npm
id: check_npm
env:
NAME: ${{ steps.pkg.outputs.name }}
VER: ${{ steps.pkg.outputs.version }}
shell: bash
run: |
set -euo pipefail
STATUS=0
OUTPUT=$(npm view "${NAME}@${VER}" --json 2>&1) || STATUS=$?
if [ "$STATUS" -eq 0 ]; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "::warning title=Already published::${NAME}@${VER} already exists on npm. Skipping publish."
else
if echo "$OUTPUT" | grep -q "E404"; then
echo "exists=false" >> "$GITHUB_OUTPUT"
else
echo "::error title=Registry lookup failed::$OUTPUT" >&2
exit "$STATUS"
fi
fi

- name: Build package
if: steps.check_npm.outputs.exists == 'false'
run: pnpm -C packages/shared-frontend-utils build

- name: Publish package
if: steps.check_npm.outputs.exists == 'false'
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
DIST_TAG: ${{ inputs.dist_tag }}
run: pnpm publish --access public --tag "$DIST_TAG" --no-git-checks --ignore-scripts
working-directory: packages/shared-frontend-utils
Loading
Loading