chore: bump version to 0.2.151 #164
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Publish to npm | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| dry_run: | |
| description: "Dry run (skip actual publish)" | |
| required: false | |
| default: false | |
| type: boolean | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 # Full history needed for release notes generation | |
| - uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: latest | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Run tests | |
| run: bun test | |
| - name: Build packages | |
| run: bun run build | |
| - name: Setup npm auth | |
| env: | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| run: | | |
| if [ -z "$NPM_TOKEN" ]; then | |
| echo "ERROR: NPM_TOKEN secret is not set!" | |
| exit 1 | |
| fi | |
| echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc | |
| # Verify npm can authenticate (this will fail if token is invalid) | |
| npm whoami | |
| - name: Publish packages | |
| if: ${{ !inputs.dry_run }} | |
| run: | | |
| set -euo pipefail | |
| NPM_REGISTRY="https://registry.npmjs.org" | |
| PUBLISH_VERIFY_ATTEMPTS="${PUBLISH_VERIFY_ATTEMPTS:-30}" | |
| PUBLISH_VERIFY_SLEEP_SECONDS="${PUBLISH_VERIFY_SLEEP_SECONDS:-10}" | |
| # Resolve release version: from tag (e.g. v0.2.10 -> 0.2.10) or from core's package.json | |
| if [[ "$GITHUB_REF" == refs/tags/v* ]]; then | |
| RELEASE_VERSION="${GITHUB_REF#refs/tags/v}" | |
| else | |
| RELEASE_VERSION=$(jq -r .version packages/core/package.json) | |
| fi | |
| echo "Using release version: $RELEASE_VERSION" | |
| echo "Using npm registry: $NPM_REGISTRY" | |
| npm_registry_config="$(npm config get registry | tr -d '[:space:]' | sed 's:/*$::')" | |
| if [[ "$npm_registry_config" != "$NPM_REGISTRY" ]]; then | |
| echo "ERROR: npm is configured for unexpected registry: ${npm_registry_config}" | |
| exit 1 | |
| fi | |
| npm_dry_run="$(npm config get dry-run | tr -d '[:space:]')" | |
| if [[ "$npm_dry_run" == "true" ]]; then | |
| echo "ERROR: npm dry-run is enabled; refusing to run publish workflow." | |
| exit 1 | |
| fi | |
| rewrite_workspace_data_slot_deps() { | |
| local manifest="$1" | |
| local tmp_manifest | |
| tmp_manifest="${manifest}.tmp" | |
| jq --arg v "$RELEASE_VERSION" ' | |
| . as $manifest | | |
| def rewrite_deps: | |
| if type == "object" then | |
| with_entries( | |
| if (.key | startswith("@data-slot/")) and (.key != ($manifest.name // "")) | |
| then .value = $v | |
| else . | |
| end | |
| ) | |
| else . | |
| end; | |
| if has("dependencies") then .dependencies |= rewrite_deps else . end | |
| | if has("devDependencies") then .devDependencies |= rewrite_deps else . end | |
| | if has("peerDependencies") then .peerDependencies |= rewrite_deps else . end | |
| | if has("optionalDependencies") then .optionalDependencies |= rewrite_deps else . end | |
| ' "$manifest" > "$tmp_manifest" | |
| mv "$tmp_manifest" "$manifest" | |
| } | |
| wait_for_registry_package_version() { | |
| local pkg="$1" | |
| local version="$2" | |
| local attempts="$PUBLISH_VERIFY_ATTEMPTS" | |
| local sleep_seconds="$PUBLISH_VERIFY_SLEEP_SECONDS" | |
| local pkg_encoded | |
| local status_code | |
| local i | |
| pkg_encoded="$(jq -nr --arg v "$pkg" '$v|@uri')" | |
| for ((i = 1; i <= attempts; i++)); do | |
| status_code="$( | |
| curl -sS -o /dev/null -w "%{http_code}" "${NPM_REGISTRY}/${pkg_encoded}/${version}" || true | |
| )" | |
| if [[ "$status_code" == "200" ]]; then | |
| echo " [OK] ${pkg}@${version} is available" | |
| return 0 | |
| fi | |
| if ((i < attempts)); then | |
| echo " ... ${pkg}@${version} not visible yet (HTTP ${status_code}, attempt ${i}/${attempts}); retrying in ${sleep_seconds}s" | |
| sleep "$sleep_seconds" | |
| fi | |
| done | |
| echo "ERROR: ${pkg}@${version} not available on npm after ${attempts} attempts (last HTTP ${status_code})" | |
| echo "Debug: npm view ${pkg} versions --json --prefer-online" | |
| npm view "$pkg" versions --json --prefer-online --registry "$NPM_REGISTRY" || true | |
| echo "Debug: registry dist-tags for ${pkg}" | |
| curl -sS "${NPM_REGISTRY}/${pkg_encoded}" | jq '.["dist-tags"] // {}' || true | |
| return 1 | |
| } | |
| # Helper function: pack with bun, rewrite workspace deps, validate packed manifest, then publish extracted contents. | |
| publish_pkg() { | |
| local dir="$1" | |
| pushd "$dir" >/dev/null | |
| rm -f ./*.tgz | |
| bun pm pack >/dev/null | |
| local tgz | |
| tgz="$(ls -1 *.tgz | head -n1)" | |
| [ -f "$tgz" ] || { echo "No .tgz produced in $dir"; ls -la; exit 1; } | |
| # Make tgz path absolute before changing dirs | |
| local tgz_path | |
| tgz_path="$(pwd)/$tgz" | |
| local tmp | |
| tmp="$(mktemp -d)" | |
| tar -xzf "$tgz_path" -C "$tmp" | |
| # Replace internal workspace:* deps with the release version. | |
| rewrite_workspace_data_slot_deps "$tmp/package/package.json" | |
| local pkg_name | |
| local pkg_version | |
| pkg_name="$(jq -r .name "$tmp/package/package.json")" | |
| pkg_version="$(jq -r .version "$tmp/package/package.json")" | |
| echo "=== Packed manifest for $dir ($tgz) ===" | |
| cat "$tmp/package/package.json" | |
| # Publish from extracted folder (cwd publish) | |
| pushd "$tmp/package" >/dev/null | |
| bunx npm publish --access public --provenance --registry "$NPM_REGISTRY" | |
| popd >/dev/null | |
| wait_for_registry_package_version "$pkg_name" "$pkg_version" | |
| rm -rf "$tmp" | |
| rm -f "$tgz_path" | |
| popd >/dev/null | |
| } | |
| # Publish in dependency order (core first) | |
| publish_pkg packages/core | |
| publish_pkg packages/accordion | |
| publish_pkg packages/dialog | |
| publish_pkg packages/alert-dialog | |
| publish_pkg packages/collapsible | |
| publish_pkg packages/navigation-menu | |
| publish_pkg packages/popover | |
| publish_pkg packages/tabs | |
| publish_pkg packages/tooltip | |
| publish_pkg packages/dropdown-menu | |
| publish_pkg packages/slider | |
| publish_pkg packages/toggle | |
| publish_pkg packages/toggle-group | |
| publish_pkg packages/select | |
| publish_pkg packages/combobox | |
| publish_pkg packages/hover-card | |
| publish_pkg packages/command | |
| publish_pkg packages/ui | |
| - name: Dry run - show what would be published | |
| if: ${{ inputs.dry_run }} | |
| run: | | |
| echo "Would publish the following packages:" | |
| for pkg in packages/*/; do | |
| name=$(jq -r .name "$pkg/package.json") | |
| version=$(jq -r .version "$pkg/package.json") | |
| echo " $name@$version" | |
| done | |
| - name: Generate Release Notes | |
| if: ${{ !inputs.dry_run && startsWith(github.ref, 'refs/tags/') }} | |
| id: release_notes | |
| env: | |
| OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} | |
| run: | | |
| if [ -z "$OPENAI_API_KEY" ]; then | |
| echo "OPENAI_API_KEY not set, using default release notes" | |
| echo "use_default=true" >> $GITHUB_OUTPUT | |
| else | |
| bun run scripts/generate-release-notes.ts ${{ github.ref_name }} > release-notes.md | |
| echo "use_default=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Create GitHub Release | |
| if: ${{ !inputs.dry_run && startsWith(github.ref, 'refs/tags/') }} | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| body_path: ${{ steps.release_notes.outputs.use_default == 'false' && 'release-notes.md' || '' }} | |
| generate_release_notes: ${{ steps.release_notes.outputs.use_default == 'true' }} |