diff --git a/.github/workflows/publish-desktop-ui-on-merge.yaml b/.github/workflows/publish-desktop-ui-on-merge.yaml new file mode 100644 index 000000000..b1adaa0c2 --- /dev/null +++ b/.github/workflows/publish-desktop-ui-on-merge.yaml @@ -0,0 +1,59 @@ +name: Publish Desktop UI on PR Merge + +on: + pull_request: + types: [ closed ] + branches: [ main, core/* ] + paths: + - 'apps/desktop-ui/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@v5 + with: + ref: ${{ github.event.pull_request.merge_commit_sha }} + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: '24.x' + + - name: Read desktop-ui version + id: get_version + run: | + VERSION=$(node -p "require('./apps/desktop-ui/package.json').version") + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Determine dist-tag + id: dist + env: + VERSION: ${{ steps.get_version.outputs.version }} + run: | + 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 Desktop UI to npm + needs: resolve + uses: ./.github/workflows/publish-desktop-ui.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 }} + diff --git a/.github/workflows/publish-desktop-ui.yaml b/.github/workflows/publish-desktop-ui.yaml new file mode 100644 index 000000000..92324d2f5 --- /dev/null +++ b/.github/workflows/publish-desktop-ui.yaml @@ -0,0 +1,205 @@ +name: Publish Desktop UI + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to publish (e.g., 1.2.3)' + 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-desktop-ui-${{ github.workflow }}-${{ inputs.version }}-${{ inputs.dist_tag }} + cancel-in-progress: false + +jobs: + publish_desktop_ui: + name: Publish @comfyorg/desktop-ui + runs-on: ubuntu-latest + permissions: + contents: read + env: + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' + steps: + - name: Validate inputs + env: + VERSION: ${{ inputs.version }} + shell: bash + run: | + set -euo pipefail + SEMVER_REGEX='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$' + if [[ ! "$VERSION" =~ $SEMVER_REGEX ]]; then + echo "::error title=Invalid version::Version '$VERSION' must follow semantic versioning (x.y.z[-suffix][+build])" >&2 + exit 1 + fi + + - name: Determine ref to checkout + id: resolve_ref + env: + REF: ${{ inputs.ref }} + VERSION: ${{ inputs.version }} + shell: bash + run: | + set -euo pipefail + if [ -n "$REF" ]; then + 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" + else + echo "ref=refs/tags/v$VERSION" >> "$GITHUB_OUTPUT" + fi + + - name: Checkout repository + uses: actions/checkout@v5 + with: + ref: ${{ steps.resolve_ref.outputs.ref }} + fetch-depth: 1 + persist-credentials: false + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: '24.x' + cache: 'pnpm' + registry-url: https://registry.npmjs.org + + - name: Install dependencies + run: pnpm install --frozen-lockfile --ignore-scripts + + - name: Build Desktop UI + run: pnpm build:desktop + + - name: Prepare npm package + id: pkg + shell: bash + run: | + set -euo pipefail + APP_PKG=apps/desktop-ui/package.json + ROOT_PKG=package.json + + NAME=$(jq -r .name "$APP_PKG") + APP_VERSION=$(jq -r .version "$APP_PKG") + ROOT_LICENSE=$(jq -r .license "$ROOT_PKG") + REPO=$(jq -r .repository "$ROOT_PKG") + + if [ -z "$NAME" ] || [ "$NAME" = "null" ]; then + echo "::error title=Missing name::apps/desktop-ui/package.json is missing 'name'" >&2 + exit 1 + fi + + INPUT_VERSION="${{ inputs.version }}" + if [ "$APP_VERSION" != "$INPUT_VERSION" ]; then + echo "::error title=Version mismatch::apps/desktop-ui version $APP_VERSION does not match input $INPUT_VERSION" >&2 + exit 1 + fi + + if [ ! -d apps/desktop-ui/dist ]; then + echo "::error title=Missing build::apps/desktop-ui/dist not found. Did build succeed?" >&2 + exit 1 + fi + + PUBLISH_DIR=apps/desktop-ui/.npm-publish + rm -rf "$PUBLISH_DIR" + mkdir -p "$PUBLISH_DIR" + cp -R apps/desktop-ui/dist "$PUBLISH_DIR/dist" + + INPUT_VERSION="${{ inputs.version }}" + jq -n \ + --arg name "$NAME" \ + --arg version "$INPUT_VERSION" \ + --arg description "Static assets for the ComfyUI Desktop UI" \ + --arg license "$ROOT_LICENSE" \ + --arg repository "$REPO" \ + '{ + name: $name, + version: $version, + description: $description, + license: $license, + repository: $repository, + type: "module", + private: false, + files: ["dist"], + publishConfig: { access: "public" } + }' > "$PUBLISH_DIR/package.json" + + if [ -f apps/desktop-ui/README.md ]; then + cp apps/desktop-ui/README.md "$PUBLISH_DIR/README.md" + fi + + echo "publish_dir=$PUBLISH_DIR" >> "$GITHUB_OUTPUT" + echo "name=$NAME" >> "$GITHUB_OUTPUT" + + - name: Pack (preview only) + shell: bash + working-directory: ${{ steps.pkg.outputs.publish_dir }} + run: | + set -euo pipefail + npm pack --json | tee pack-result.json + + - name: Upload package tarball artifact + uses: actions/upload-artifact@v4 + with: + name: desktop-ui-npm-tarball-${{ inputs.version }} + path: ${{ steps.pkg.outputs.publish_dir }}/*.tgz + if-no-files-found: error + + - name: Check if version already on npm + id: check_npm + env: + NAME: ${{ steps.pkg.outputs.name }} + VER: ${{ inputs.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: 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: ${{ steps.pkg.outputs.publish_dir }} diff --git a/.github/workflows/version-bump-desktop-ui.yaml b/.github/workflows/version-bump-desktop-ui.yaml new file mode 100644 index 000000000..6d5d01c67 --- /dev/null +++ b/.github/workflows/version-bump-desktop-ui.yaml @@ -0,0 +1,71 @@ +name: Version Bump Desktop UI + +on: + workflow_dispatch: + inputs: + version_type: + description: 'Version increment type' + required: true + default: 'patch' + type: 'choice' + options: [patch, minor, major, prepatch, preminor, premajor, prerelease] + pre_release: + description: Pre-release ID (suffix) + required: false + default: '' + type: string + +jobs: + bump-version-desktop-ui: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + with: + persist-credentials: false + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v5 + with: + node-version: '24.x' + cache: 'pnpm' + + - name: Bump desktop-ui version + id: bump-version + env: + VERSION_TYPE: ${{ github.event.inputs.version_type }} + PRE_RELEASE: ${{ github.event.inputs.pre_release }} + run: | + pnpm -C apps/desktop-ui version "$VERSION_TYPE" --preid "$PRE_RELEASE" --no-git-tag-version + NEW_VERSION=$(node -p "require('./apps/desktop-ui/package.json').version") + echo "NEW_VERSION=$NEW_VERSION" >> $GITHUB_OUTPUT + + - name: Format PR string + id: capitalised + env: + VERSION_TYPE: ${{ github.event.inputs.version_type }} + run: | + echo "capitalised=${VERSION_TYPE@u}" >> $GITHUB_OUTPUT + + - name: Create Pull Request + uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e + with: + token: ${{ secrets.PR_GH_TOKEN }} + commit-message: '[release] Increment desktop-ui to ${{ steps.bump-version.outputs.NEW_VERSION }}' + title: desktop-ui ${{ steps.bump-version.outputs.NEW_VERSION }} + body: | + ${{ steps.capitalised.outputs.capitalised }} version increment for @comfyorg/desktop-ui to ${{ steps.bump-version.outputs.NEW_VERSION }} + branch: desktop-ui-version-bump-${{ steps.bump-version.outputs.NEW_VERSION }} + base: main + labels: | + Release +