Skip to content

Publish

Publish #23

Workflow file for this run

name: Publish
on:
workflow_dispatch:
inputs:
package:
description: 'Package to release'
required: true
type: choice
options:
- hikkaku
- create-hikkaku
- vite-plugin-turbowarp-packager
release_type:
description: 'Version bump type'
required: true
type: choice
options:
- patch
- minor
- major
permissions:
id-token: write
contents: write
jobs:
publish:
runs-on: ubuntu-latest
concurrency:
group: publish-${{ inputs.package }}
cancel-in-progress: false
permissions:
contents: write
id-token: write
env:
GH_TOKEN: ${{ github.token }}
PACKAGE_NAME: ${{ inputs.package }}
INPUT_RELEASE_TYPE: ${{ inputs.release_type }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- uses: actions/setup-node@v4
with:
node-version: '24'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Resolve release metadata
id: metadata
shell: bash
run: |
package="$PACKAGE_NAME"
release_type="$INPUT_RELEASE_TYPE"
if ! [[ "$package" =~ ^(hikkaku|create-hikkaku|vite-plugin-turbowarp-packager)$ ]]; then
echo "Unsupported package: $package"
exit 1
fi
if ! [[ "$release_type" =~ ^(major|minor|patch)$ ]]; then
echo "Invalid release_type: $release_type"
echo "Supported values: major, minor, patch"
exit 1
fi
# Derive current version from latest tag for this package
# If no tags exist, fall back to package.json version
# Note: Uses git's version sorting which correctly handles semver including prereleases
latest_tag=$(git tag -l "$package@*" --sort=-version:refname | head -n1)
if [ -n "$latest_tag" ]; then
# Extract version from tag (format: package@version)
current_version="${latest_tag#$package@}"
echo "Found latest tag: $latest_tag (version: $current_version)"
else
# No tags exist, use package.json version as starting point
package_json_path="packages/$package/package.json"
if [ ! -r "$package_json_path" ]; then
echo "package.json not found or not readable: $package_json_path"
exit 1
fi
current_version="$(node -e "const fs=require('fs');const pkg=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));process.stdout.write(typeof pkg.version==='string'?pkg.version.trim():'')" "$package_json_path")"
if [ -z "$current_version" ]; then
echo "package.json does not contain a valid version field: $package_json_path"
exit 1
fi
echo "No existing tags found, using package.json version: $current_version"
fi
if ! [[ "$current_version" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)([.-][0-9A-Za-z.-]+)?(\+[0-9A-Za-z.-]+)?$ ]]; then
echo "Invalid current package version: $current_version"
exit 1
fi
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
patch="${BASH_REMATCH[3]}"
case "$release_type" in
major)
major=$((major + 1))
minor=0
patch=0
;;
minor)
minor=$((minor + 1))
patch=0
;;
patch)
patch=$((patch + 1))
;;
esac
version="$major.$minor.$patch"
tag="$package@$version"
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
echo "Tag already exists: $tag"
exit 1
fi
if gh release view "$tag" >/dev/null 2>&1; then
echo "Release already exists: $tag"
exit 1
fi
echo "package=$package" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
- name: Ensure workflow runs on branch
run: |
if [[ '${{ github.ref_type }}' != 'branch' ]]; then
echo "This workflow must run on a branch ref to push version updates."
echo "Current ref_type: ${{ github.ref_type }}"
exit 1
fi
- name: Update package version
run: |
node -e "const fs=require('fs');const path='packages/${{ steps.metadata.outputs.package }}/package.json';const version='${{ steps.metadata.outputs.version }}';const pkg=JSON.parse(fs.readFileSync(path,'utf8'));pkg.version=version;const hasPrivate=Object.prototype.hasOwnProperty.call(pkg,'private');if(hasPrivate&&(pkg.name==='create-hikkaku'||pkg.name==='vite-plugin-turbowarp-packager')){pkg.private=false;}fs.writeFileSync(path,JSON.stringify(pkg,null,2)+'\n');"
- name: Build hikkaku
if: steps.metadata.outputs.package == 'hikkaku'
run: bun run --filter hikkaku build
- name: Build create-hikkaku
if: steps.metadata.outputs.package == 'create-hikkaku'
run: bun run --filter create-hikkaku build
- name: Build vite-plugin-turbowarp-packager
if: steps.metadata.outputs.package == 'vite-plugin-turbowarp-packager'
run: bun run --filter vite-plugin-turbowarp-packager build
- name: Build gpts zip
if: steps.metadata.outputs.package == 'hikkaku'
run: bun run --filter gpts-zip build
- name: Resolve publish directory
id: publish_dir
shell: bash
run: |
case '${{ steps.metadata.outputs.package }}' in
hikkaku)
dir='packages/hikkaku/dist'
;;
create-hikkaku)
dir='packages/create-hikkaku'
;;
vite-plugin-turbowarp-packager)
dir='packages/vite-plugin-turbowarp-packager'
;;
*)
echo "Unsupported package: ${{ steps.metadata.outputs.package }}"
exit 1
;;
esac
echo "dir=$dir" >> "$GITHUB_OUTPUT"
- name: Pack package tarball
id: pack
shell: bash
run: |
publish_dir='${{ steps.publish_dir.outputs.dir }}'
tarball_output="$(cd "$publish_dir" && bun pm pack --quiet --destination "$RUNNER_TEMP")"
tarball_output="$(echo "$tarball_output" | tr -d '\n')"
if [[ "$tarball_output" = /* ]]; then
tarball_path="$tarball_output"
else
tarball_path="$RUNNER_TEMP/$tarball_output"
fi
if [[ ! -f "$tarball_path" ]]; then
echo "Tarball was not generated at expected path: $tarball_path"
exit 1
fi
echo "path=$tarball_path" >> "$GITHUB_OUTPUT"
- name: Publish package tarball to npm
run: npm publish '${{ steps.pack.outputs.path }}' --provenance --access public
- name: Commit and push version update
id: version_commit
shell: bash
run: |
file_path="packages/${{ steps.metadata.outputs.package }}/package.json"
git config user.name 'github-actions[bot]'
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
git add "$file_path"
if git diff --cached --quiet; then
echo "No version updates to commit."
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
exit 0
fi
git commit -m 'chore(release): bump ${{ steps.metadata.outputs.package }} to v${{ steps.metadata.outputs.version }}'
git push origin "HEAD:${{ github.ref_name }}"
echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Create release with generated notes
run: |
if [[ '${{ steps.metadata.outputs.package }}' == 'hikkaku' ]]; then
gh release create '${{ steps.metadata.outputs.tag }}' \
'packages/gpts-zip/dist.zip#gpts.zip' \
--generate-notes \
--target '${{ steps.version_commit.outputs.sha }}'
else
gh release create '${{ steps.metadata.outputs.tag }}' \
--generate-notes \
--target '${{ steps.version_commit.outputs.sha }}'
fi