Skip to content

fix: use HADOKU_SITE_TOKEN for cross-repo package install in CI #212

fix: use HADOKU_SITE_TOKEN for cross-repo package install in CI

fix: use HADOKU_SITE_TOKEN for cross-repo package install in CI #212

Workflow file for this run

name: Publish Package
on:
push:
branches:
- main # Trigger on every push to main
workflow_dispatch: # Allow manual trigger
permissions:
contents: write # Changed from 'read' to allow auto-bumping versions
packages: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: https://npm.pkg.github.com
scope: '@wolffm'
cache: pnpm
- name: Configure npm for GitHub Packages
run: |
echo "//npm.pkg.github.com/:_authToken=${{ secrets.HADOKU_SITE_TOKEN }}" > ~/.npmrc
echo "@wolffm:registry=https://npm.pkg.github.com" >> ~/.npmrc
env:
NODE_AUTH_TOKEN: ${{ secrets.HADOKU_SITE_TOKEN }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
env:
NODE_AUTH_TOKEN: ${{ secrets.HADOKU_SITE_TOKEN }}
# Validate that required manually-maintained files exist
- name: Validate required source files
run: |
echo "Checking for required manually-maintained files..."
missing_files=0
# Check for entry.d.ts (required by vite.config.ts copy-types plugin)
if [ ! -f "src/app/entry.d.ts" ]; then
echo "❌ ERROR: src/app/entry.d.ts is missing!"
echo " This file should be committed (exception in .gitignore)"
missing_files=1
else
echo "✓ src/app/entry.d.ts exists"
fi
# Check that CSS files exist in task-ui-components (required by copy-css script)
if [ ! -f "task-ui-components/src/theme-picker.css" ]; then
echo "❌ ERROR: task-ui-components/src/theme-picker.css is missing!"
missing_files=1
else
echo "✓ task-ui-components/src/theme-picker.css exists"
fi
if [ ! -f "task-ui-components/src/toaster.css" ]; then
echo "❌ ERROR: task-ui-components/src/toaster.css is missing!"
missing_files=1
else
echo "✓ task-ui-components/src/toaster.css exists"
fi
if [ ! -f "task-ui-components/src/context-menu.css" ]; then
echo "❌ ERROR: task-ui-components/src/context-menu.css is missing!"
missing_files=1
else
echo "✓ task-ui-components/src/context-menu.css exists"
fi
# Check themes CSS file
if [ ! -f "themes/src/style.css" ]; then
echo "❌ ERROR: themes/src/style.css is missing!"
missing_files=1
else
echo "✓ themes/src/style.css exists"
fi
if [ $missing_files -eq 1 ]; then
echo ""
echo "💡 Tip: Check .gitignore for overly broad ignore patterns"
echo " that might be excluding required source files."
exit 1
fi
echo "✅ All required source files present"
# Build in dependency order: UI Components → Themes → Task
- name: Build UI Components package
run: pnpm --filter @wolffm/task-ui-components run build
- name: Build Themes package
run: pnpm --filter @wolffm/themes run build
- name: Build Task package
run: pnpm run build:all
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Debug - Show changed files
run: |
echo "Files changed in this push:"
git diff --name-only HEAD~1 HEAD
echo "---"
# Fallback version bump check - ensures version was incremented even if pre-commit hook failed
# IMPORTANT: These patterns must match the pre-commit hook patterns in .husky/pre-commit
- name: Verify version bump (fallback check)
id: version_check
run: |
echo "🔍 Checking if version was properly bumped..."
# Function to check if a package version was published
check_version_published() {
local pkg_name=$1
local pkg_path=$2
local current_version=$(node -p "require('$pkg_path/package.json').version")
echo "Checking $pkg_name@$current_version..."
# Try to fetch the package info from registry
if npm view "$pkg_name@$current_version" version 2>/dev/null | grep -q "$current_version"; then
echo "⚠️ $pkg_name@$current_version already exists in registry!"
return 1
else
echo "✓ $pkg_name@$current_version is a new version"
return 0
fi
}
version_issues=0
needs_ui_bump=false
needs_themes_bump=false
needs_task_bump=false
# Check task-ui-components if SOURCE files changed (matches pre-commit hook pattern)
# Pattern: task-ui-components/(src/|package.json|tsconfig.|vite.config.)
if git diff --name-only HEAD~1 HEAD | grep -qE "^task-ui-components/(src/|package\.json|tsconfig\.|vite\.config\.)"; then
echo "📦 task-ui-components source files changed, checking version..."
if ! check_version_published "@wolffm/task-ui-components" "./task-ui-components"; then
echo "::warning::task-ui-components version was not bumped! Will auto-bump."
version_issues=1
needs_ui_bump=true
fi
else
echo "ℹ️ task-ui-components: no source changes (skipping version check)"
fi
# Check themes if SOURCE files changed (matches pre-commit hook pattern)
# Pattern: themes/(src/|package.json|tsconfig.|vite.config.)
if git diff --name-only HEAD~1 HEAD | grep -qE "^themes/(src/|package\.json|tsconfig\.|vite\.config\.)"; then
echo "📦 themes source files changed, checking version..."
if ! check_version_published "@wolffm/themes" "./themes"; then
echo "::warning::themes version was not bumped! Will auto-bump."
version_issues=1
needs_themes_bump=true
fi
else
echo "ℹ️ themes: no source changes (skipping version check)"
fi
# Check task package if SOURCE files changed (matches pre-commit hook pattern)
# Pattern: (src/|worker/|package.json|vite.config.|tsconfig.|tsup.) at root level
if git diff --name-only HEAD~1 HEAD | grep -qE "^(src/|worker/|package\.json|vite\.config\.|tsconfig\.|tsup\.)"; then
echo "📦 task source files changed, checking version..."
if ! check_version_published "@wolffm/task" "."; then
echo "::warning::task version was not bumped! Will auto-bump."
version_issues=1
needs_task_bump=true
fi
else
echo "ℹ️ task: no source changes (skipping version check)"
fi
# Export flags for the auto-bump step
echo "version_issues=$version_issues" >> $GITHUB_OUTPUT
echo "needs_ui_bump=$needs_ui_bump" >> $GITHUB_OUTPUT
echo "needs_themes_bump=$needs_themes_bump" >> $GITHUB_OUTPUT
echo "needs_task_bump=$needs_task_bump" >> $GITHUB_OUTPUT
if [ $version_issues -eq 1 ]; then
echo ""
echo "⚠️ VERSION BUMP MISSING - Will auto-bump in next step"
echo ""
echo "The pre-commit hook should have auto-bumped the version but didn't."
echo "Possible causes:"
echo " 1. Husky hooks not installed (run 'pnpm prepare')"
echo " 2. Git hooks bypassed with --no-verify"
echo " 3. Commit made by automation (Copilot, bot, etc.)"
echo ""
echo "✨ CI will auto-bump versions and continue..."
else
echo "✅ All changed packages have new versions (or no source changes requiring bump)"
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Auto-bump versions if pre-commit hook was bypassed
- name: Auto-bump versions
if: steps.version_check.outputs.version_issues == '1'
run: |
echo "🤖 Auto-bumping versions that were missed by pre-commit hook..."
# Function to bump version for a package (matches pre-commit hook logic)
bump_package_version() {
local pkg_path=$1
local pkg_name=$2
# Read current version from package.json
current_version=$(node -p "require('${pkg_path}/package.json').version")
major=$(echo "$current_version" | cut -d. -f1)
minor=$(echo "$current_version" | cut -d. -f2)
patch=$(echo "$current_version" | cut -d. -f3)
# Rollover at .20 to keep patch numbers manageable
if [[ $patch -eq 20 ]]; then
new_minor=$((minor + 1))
new_version="$major.$new_minor.0"
echo "🚀 $pkg_name: Rolling over to minor version"
else
new_patch=$((patch + 1))
new_version="$major.$minor.$new_patch"
echo "📈 $pkg_name: Incrementing patch version"
fi
# Update package.json with new version
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('${pkg_path}/package.json', 'utf8'));
pkg.version = '$new_version';
fs.writeFileSync('${pkg_path}/package.json', JSON.stringify(pkg, null, 2) + '\n');
"
echo "✅ $pkg_name: Version bumped: $current_version → $new_version"
}
# Handle dependency chain: if ui-components bumps, themes and task must also bump
needs_ui_bump="${{ steps.version_check.outputs.needs_ui_bump }}"
needs_themes_bump="${{ steps.version_check.outputs.needs_themes_bump }}"
needs_task_bump="${{ steps.version_check.outputs.needs_task_bump }}"
# If ui-components needs bump, dependents must also bump
if [[ "$needs_ui_bump" = "true" ]]; then
echo "📦 task-ui-components changed → bumping dependent packages (themes, task)"
needs_themes_bump=true
needs_task_bump=true
fi
# If themes needs bump, task must also bump
if [[ "$needs_themes_bump" = "true" ]]; then
echo "📦 themes changed → bumping dependent package (task)"
needs_task_bump=true
fi
# Perform bumps in dependency order
if [[ "$needs_ui_bump" = "true" ]]; then
bump_package_version "./task-ui-components" "@wolffm/task-ui-components"
fi
if [[ "$needs_themes_bump" = "true" ]]; then
bump_package_version "./themes" "@wolffm/themes"
fi
if [[ "$needs_task_bump" = "true" ]]; then
bump_package_version "." "@wolffm/task"
fi
# Update lock file
echo "🔄 Updating lock file..."
pnpm install --lockfile-only
# Configure git
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Commit and push changes
git add -A
git commit -m "chore: auto-bump versions (pre-commit hook was bypassed)"
git push
echo "✅ Versions auto-bumped and pushed successfully!"
echo ""
echo "🔄 Rebuilding with new versions..."
# Rebuild if versions were auto-bumped
- name: Rebuild after version bump
if: steps.version_check.outputs.version_issues == '1'
run: |
echo "🔨 Rebuilding packages with new versions..."
# Reinstall to pick up new versions
pnpm install --frozen-lockfile
# Rebuild in dependency order
pnpm --filter @wolffm/task-ui-components run build
pnpm --filter @wolffm/themes run build
pnpm run build:all
echo "✅ Rebuild complete!"
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check if themes package changed
id: themes_changed
run: |
if git diff --name-only HEAD~1 HEAD | grep -q "^themes/"; then
echo "changed=true" >> $GITHUB_OUTPUT
echo "✓ Themes package has changes"
else
echo "changed=false" >> $GITHUB_OUTPUT
echo "✗ No changes in themes package"
fi
- name: Check if task-ui-components package changed
id: ui_components_changed
run: |
if git diff --name-only HEAD~1 HEAD | grep -q "^task-ui-components/"; then
echo "changed=true" >> $GITHUB_OUTPUT
echo "✓ UI Components package has changes"
else
echo "changed=false" >> $GITHUB_OUTPUT
echo "✗ No changes in UI components package"
fi
- name: Check if task package changed
id: task_changed
run: |
# Check if any files changed outside of themes/ and task-ui-components/ directories
if git diff --name-only HEAD~1 HEAD | grep -Ev "^(themes|task-ui-components)/" | grep -qE "^(src/|worker/|package\.json|vite\.config\.|tsconfig\.|tsup\.)"; then
echo "changed=true" >> $GITHUB_OUTPUT
echo "✓ Task package has changes"
else
echo "changed=false" >> $GITHUB_OUTPUT
echo "✗ No changes in task package"
fi
# Publish in dependency order: UI Components → Themes → Task
# This ensures dependencies are available before dependent packages
- name: Publish UI Components package
if: steps.ui_components_changed.outputs.changed == 'true'
run: pnpm --filter @wolffm/task-ui-components publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish Themes package
if: steps.themes_changed.outputs.changed == 'true'
run: pnpm --filter @wolffm/themes publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish Task package
if: steps.task_changed.outputs.changed == 'true'
run: pnpm --filter @wolffm/task publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Notify parent about package updates
if: steps.themes_changed.outputs.changed == 'true' || steps.ui_components_changed.outputs.changed == 'true' || steps.task_changed.outputs.changed == 'true'
env:
HADOKU_SITE_TOKEN: ${{ secrets.HADOKU_SITE_TOKEN }}
run: |
echo "Notifying hadoku_site about package updates..."
if [ -z "$HADOKU_SITE_TOKEN" ]; then
echo "⚠️ Warning: HADOKU_SITE_TOKEN not available, skipping notification"
exit 0
fi
# Build array of updated packages in dependency order
updated_packages="["
first=true
# UI Components first (no dependencies)
if [ "${{ steps.ui_components_changed.outputs.changed }}" = "true" ]; then
updated_packages="${updated_packages}\"@wolffm/task-ui-components\""
first=false
fi
# Themes second (depends on UI Components)
if [ "${{ steps.themes_changed.outputs.changed }}" = "true" ]; then
if [ "$first" = "false" ]; then
updated_packages="${updated_packages},"
fi
updated_packages="${updated_packages}\"@wolffm/themes\""
first=false
fi
# Task last (depends on both)
if [ "${{ steps.task_changed.outputs.changed }}" = "true" ]; then
if [ "$first" = "false" ]; then
updated_packages="${updated_packages},"
fi
updated_packages="${updated_packages}\"@wolffm/task\""
fi
updated_packages="${updated_packages}]"
echo "Updated packages: $updated_packages"
payload=$(cat <<EOF
{
"event_type": "packages_updated",
"client_payload": {
"packages": $updated_packages,
"sha": "${{ github.sha }}",
"ref": "${{ github.ref }}"
}
}
EOF
)
status_code=$(curl -sS \
-o /dev/null \
-w "%{http_code}" \
-X POST "https://api.github.com/repos/WolffM/hadoku_site/dispatches" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $HADOKU_SITE_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-d "$payload")
if [ "$status_code" = "204" ]; then
echo "✅ Notified hadoku_site about package updates"
else
echo "⚠️ Failed to notify hadoku_site (HTTP $status_code)"
fi