Skip to content

🤖 fix: make settings titlebar control toggle open/close (#2429) #1769

🤖 fix: make settings titlebar control toggle open/close (#2429)

🤖 fix: make settings titlebar control toggle open/close (#2429) #1769

Workflow file for this run

name: Publish to NPM
# Uses NPM Trusted Publishing with OIDC - no secrets required!
#
# SETUP (one-time, on npmjs.com):
# 1. Go to https://www.npmjs.com/package/mux/access
# 2. Under "Trusted Publisher", click "GitHub Actions"
# 3. Configure:
# - Owner: coder
# - Repository: mux
# - Workflow filename: publish-npm.yml
# - Environment: (leave blank)
# 4. Click "Set up connection"
on:
push:
branches:
- main
tags:
- "v*"
workflow_dispatch:
jobs:
publish:
name: Publish to NPM
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for OIDC trusted publishing
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
fetch-depth: 0 # Required for git describe to find tags
persist-credentials: false
- uses: ./.github/actions/setup-mux
# Setup Node.js 24+ for npm v11+ required by OIDC trusted publishing.
# Node 22 ships with npm 10.x which does NOT support OIDC.
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Generate unique version from git
id: version
run: |
# Get base version from package.json
BASE_VERSION=$(node -p "require('./package.json').version")
# Generate git describe version (for debugging; used indirectly via commits_since_tag)
git describe --tags --always --dirty 2>/dev/null || echo "unknown"
if [[ $GITHUB_REF == refs/tags/* ]]; then
# For tags, use the base version as-is (stable release)
NPM_VERSION="${BASE_VERSION}"
NPM_TAG="latest"
echo "Publishing stable release: ${NPM_VERSION}"
else
# For main branch, create a pre-release version using git describe
# Format: 0.3.0-next.5.g1a2b3c4 (base-next.commits.hash)
GIT_COMMIT=$(git rev-parse --short HEAD)
TAG_BASE=$(git describe --tags --abbrev=0 2>/dev/null || echo HEAD)
COMMITS_SINCE_TAG=$(git rev-list --count HEAD "^$TAG_BASE" 2>/dev/null || echo "0")
NPM_VERSION="${BASE_VERSION}-next.${COMMITS_SINCE_TAG}.g${GIT_COMMIT}"
NPM_TAG="next"
echo "Publishing pre-release: ${NPM_VERSION}"
fi
echo "version=${NPM_VERSION}" >> "$GITHUB_OUTPUT"
echo "tag=${NPM_TAG}" >> "$GITHUB_OUTPUT"
# Update package.json with the new version
node -e "const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('package.json')); pkg.version = '${NPM_VERSION}'; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');"
echo "Updated package.json to version ${NPM_VERSION}"
- name: Generate version file
run: ./scripts/generate-version.sh
- name: Generate npm shrinkwrap
run: ./scripts/generate-npm-shrinkwrap.sh
- name: Build application
run: make build
- name: Pack npm package for smoke test
run: npm pack
- name: Find package tarball
id: find-tarball
run: |
# shellcheck disable=SC2012 # ls is fine here - known filename pattern in controlled directory
TARBALL=$(ls mux-*.tgz | head -1)
echo "tarball=$TARBALL" >> "$GITHUB_OUTPUT"
echo "Found package: $TARBALL"
- name: Run smoke test
env:
PACKAGE_TARBALL: ${{ steps.find-tarball.outputs.tarball }}
SERVER_PORT: 3000
SERVER_HOST: localhost
STARTUP_TIMEOUT: 30
run: |
./scripts/smoke-test.sh
- name: Upload server logs on smoke test failure
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: smoke-test-logs
path: |
/tmp/mux-smoke-test-*/server.log
if-no-files-found: warn
retention-days: 7
# Run a second smoke test without npm-shrinkwrap.json to catch dependency
# resolution issues that affect `bun x mux@latest` and other tools that
# don't respect shrinkwrap. Uses a different port to avoid conflicts.
- name: Run smoke test (without shrinkwrap)
env:
PACKAGE_TARBALL: ${{ steps.find-tarball.outputs.tarball }}
SERVER_PORT: 3001
SERVER_HOST: localhost
STARTUP_TIMEOUT: 30
SKIP_SHRINKWRAP: "1"
run: |
./scripts/smoke-test.sh
- name: Upload server logs on no-shrinkwrap smoke test failure
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: smoke-test-no-shrinkwrap-logs
path: |
/tmp/mux-smoke-test-*/server.log
if-no-files-found: warn
retention-days: 7
- name: Clean up tarball
if: always()
run: rm -f mux-*.tgz
- name: Check if version exists
id: check-exists
run: |
PACKAGE_NAME=$(node -p "require('./package.json').name")
VERSION="${STEPS_VERSION_OUTPUTS_VERSION}"
if npm view "${PACKAGE_NAME}@${VERSION}" version &>/dev/null; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Version ${VERSION} already exists on npm"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "Version ${VERSION} does not exist, will publish"
fi
env:
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
- name: Publish to NPM
if: steps.check-exists.outputs.exists == 'false'
run: npm publish --tag "$STEPS_VERSION_OUTPUTS_TAG"
env:
STEPS_VERSION_OUTPUTS_TAG: ${{ steps.version.outputs.tag }}
- name: Skip (version already exists)
if: steps.check-exists.outputs.exists == 'true'
run: |
echo "Version ${STEPS_VERSION_OUTPUTS_VERSION} already exists on npm; skipping publish."
env:
STEPS_VERSION_OUTPUTS_VERSION: ${{ steps.version.outputs.version }}
- name: Generate chat-components version
id: chat-components-version
working-directory: packages/chat-components
run: |
# Get base version from package.json
BASE_VERSION=$(node -p "require('./package.json').version")
# Generate git describe version (for debugging; used indirectly via commits_since_tag)
git describe --tags --always --dirty 2>/dev/null || echo "unknown"
if [[ $GITHUB_REF == refs/tags/* ]]; then
# For tags, use the base version as-is (stable release)
NPM_VERSION="${BASE_VERSION}"
NPM_TAG="latest"
echo "Publishing stable release: ${NPM_VERSION}"
else
# For main branch, create a pre-release version using git describe
# Format: 0.3.0-next.5.g1a2b3c4 (base-next.commits.hash)
GIT_COMMIT=$(git rev-parse --short HEAD)
TAG_BASE=$(git describe --tags --abbrev=0 2>/dev/null || echo HEAD)
COMMITS_SINCE_TAG=$(git rev-list --count HEAD "^$TAG_BASE" 2>/dev/null || echo "0")
NPM_VERSION="${BASE_VERSION}-next.${COMMITS_SINCE_TAG}.g${GIT_COMMIT}"
NPM_TAG="next"
echo "Publishing pre-release: ${NPM_VERSION}"
fi
echo "version=${NPM_VERSION}" >> "$GITHUB_OUTPUT"
echo "tag=${NPM_TAG}" >> "$GITHUB_OUTPUT"
# Update package.json with the new version
node -e "const fs = require('fs'); const pkg = JSON.parse(fs.readFileSync('package.json')); pkg.version = '${NPM_VERSION}'; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');"
echo "Updated package.json to version ${NPM_VERSION}"
- name: Install chat-components deps
working-directory: packages/chat-components
run: bun install
- name: Build chat-components package
working-directory: packages/chat-components
run: bun run build
- name: Check if chat-components version exists
id: chat-components-check-exists
working-directory: packages/chat-components
run: |
PACKAGE_NAME=$(node -p "require('./package.json').name")
VERSION="${STEPS_CHAT_COMPONENTS_VERSION}"
if npm view "${PACKAGE_NAME}@${VERSION}" version &>/dev/null; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Version ${VERSION} already exists on npm"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "Version ${VERSION} does not exist, will publish"
fi
env:
STEPS_CHAT_COMPONENTS_VERSION: ${{ steps.chat-components-version.outputs.version }}
- name: Publish chat-components to NPM
if: steps.chat-components-check-exists.outputs.exists == 'false'
working-directory: packages/chat-components
run: npm publish --tag "$STEPS_CHAT_COMPONENTS_TAG"
env:
STEPS_CHAT_COMPONENTS_TAG: ${{ steps.chat-components-version.outputs.tag }}
- name: Skip chat-components (version already exists)
if: steps.chat-components-check-exists.outputs.exists == 'true'
run: |
echo "Version ${STEPS_CHAT_COMPONENTS_VERSION} already exists on npm; skipping publish."
env:
STEPS_CHAT_COMPONENTS_VERSION: ${{ steps.chat-components-version.outputs.version }}