fix: use HADOKU_SITE_TOKEN for cross-repo package install in CI #212
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 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 |