Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 50 additions & 56 deletions .github/scripts/configure-deps.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,71 @@
#!/usr/bin/env bun

/**
* Configure dependencies for installation
* Verify that GitHub Packages auth is available for `bun install`.
*
* This script ensures that GitHub packages authentication is properly set up
* for installing private packages from the GitHub Package Registry.
* IMPORTANT: Bun reads bunfig.toml at process startup, BEFORE this preinstall
* hook runs. That means we cannot inject PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN
* into the parent process β€” the variable must already be exported in the
* shell that invokes `bun install`. This script's job is to detect a missing
* token early and print the exact command to fix it.
*
* It runs automatically before `bun install` via the preinstall hook.
*
* Token Usage Pattern:
* - Local development: GitHub CLI token (from `gh auth token`) β†’ PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN
* - CI/CD: Uses PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN directly from secrets
* - The token is used by bunfig.toml to authenticate with npm.pkg.github.com
*
* Requirements:
* - Local development: GitHub CLI must be installed and authenticated with `read:packages` scope
* - CI/CD: PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN environment variable must be set
* Expected flow:
* - Local dev: `export PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN=$(gh auth token)` then `bun install`
* - CI/CD: PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN set from repo secrets
*/

import { $ } from 'bun';

async function configureDeps() {
try {
// Check if we're in a CI environment
const isCI =
process.env.CI === '1' || process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
const TOKEN_VAR = 'PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN';

if (isCI) {
// In CI, bunfig.toml will use PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN
if (!process.env.PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN) {
console.error('❌ PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN not found in CI');
console.error('Please ensure PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN is set in your CI secrets');
process.exit(1);
}
console.log('βœ“ Using PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN for CI authentication');
return;
}
function isCI(): boolean {
return (
process.env.CI === '1' || process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true'
);
}

// For local development, check if PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN is already set
if (process.env.PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN) {
console.log('βœ“ PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN already set in environment');
return;
}
function printLocalFix(): void {
console.error(`\n❌ ${TOKEN_VAR} is not exported in your shell.`);
console.error('\nBun reads bunfig.toml before the preinstall hook runs, so the token');
console.error('must be present in the parent shell. Run one of:\n');
console.error(' # Inline');
console.error(` export ${TOKEN_VAR}=$(gh auth token)`);
console.error(' bun install\n');
console.error(' # One-liner');
console.error(` ${TOKEN_VAR}=$(gh auth token) bun install\n`);
console.error(' # Persist β€” add to ~/.zshrc or ~/.bashrc');
console.error(` export ${TOKEN_VAR}=$(gh auth token 2>/dev/null)\n`);
console.error('If gh is not set up yet:');
console.error(' gh auth login');
console.error(' gh auth refresh -h github.com -s read:packages');
}

// Try to get token from GitHub CLI
const ghStatus = await $`gh auth status`.quiet().nothrow();
async function configureDeps() {
if (process.env[TOKEN_VAR]) {
console.log(`βœ“ ${TOKEN_VAR} is set β€” bun install will authenticate to GitHub Packages`);
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The success message asserts that bun install will authenticate, but this script doesn’t actually validate the token against GitHub Packagesβ€”only that the env var is non-empty. Consider softening the wording (e.g., β€œtoken is set”) or adding a lightweight validation if you want the message to be strictly accurate.

Suggested change
console.log(`βœ“ ${TOKEN_VAR} is set β€” bun install will authenticate to GitHub Packages`);
console.log(`βœ“ ${TOKEN_VAR} is set β€” bun install can use it to authenticate to GitHub Packages`);

Copilot uses AI. Check for mistakes.
return;
}

if (ghStatus.exitCode === 0) {
// Note: gh auth status doesn't show read:packages in the output even when it's granted
// The token will work if the user has followed the authentication steps
if (isCI()) {
console.error(`❌ ${TOKEN_VAR} not found in CI environment`);
console.error(`Set ${TOKEN_VAR} in your CI secrets and expose it to this job.`);
process.exit(1);
}

// Get the GitHub token from gh CLI and set it as PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN
const token = await $`gh auth token`.text();
process.env.PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN = token.trim();
console.log('βœ“ Using GitHub CLI token for authentication');
} else {
console.error('❌ GitHub CLI not found or not authenticated');
console.error('\nTo fix this:');
console.error('1. Install GitHub CLI: https://cli.github.com');
console.error('2. Authenticate: gh auth login');
console.error('3. Add packages scope: gh auth refresh -h github.com -s read:packages');
console.error(
'\nAlternatively, set PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN environment variable with a personal access token',
);
process.exit(1);
}
} catch (error) {
console.error('❌ Configuration failed:', error);
const ghStatus = await $`gh auth status`.quiet().nothrow();
if (ghStatus.exitCode !== 0) {
console.error('❌ GitHub CLI not found or not authenticated.\n');
console.error('1. Install GitHub CLI: https://cli.github.com');
console.error('2. Authenticate: gh auth login');
console.error('3. Add packages scope: gh auth refresh -h github.com -s read:packages');
console.error(`4. Then export ${TOKEN_VAR}=$(gh auth token) and re-run bun install.`);
Comment on lines +58 to +61
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local error path when gh is missing/not authenticated only suggests installing/authing gh, but doesn’t mention the supported fallback of setting PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN directly (e.g., a PAT with read:packages). This is a regression from the previous behavior and also contradicts the PR description (β€œmissing-gh path preserved”). Consider updating the message to include the manual env-var option so non-gh environments aren’t blocked.

Suggested change
console.error('1. Install GitHub CLI: https://cli.github.com');
console.error('2. Authenticate: gh auth login');
console.error('3. Add packages scope: gh auth refresh -h github.com -s read:packages');
console.error(`4. Then export ${TOKEN_VAR}=$(gh auth token) and re-run bun install.`);
console.error('You can fix this in either of these ways:\n');
console.error('1. Use GitHub CLI');
console.error(' - Install GitHub CLI: https://cli.github.com');
console.error(' - Authenticate: gh auth login');
console.error(' - Add packages scope: gh auth refresh -h github.com -s read:packages');
console.error(` - Then export ${TOKEN_VAR}=$(gh auth token) and re-run bun install.\n`);
console.error('2. Set the token manually');
console.error(` - Export ${TOKEN_VAR} directly in your shell before running bun install`);
console.error(' - For example, use a GitHub PAT with the read:packages scope');

Copilot uses AI. Check for mistakes.
process.exit(1);
}

printLocalFix();
process.exit(1);
}

// Only run if this is the main module
if (import.meta.main) {
configureDeps();
}
43 changes: 35 additions & 8 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,25 +103,52 @@ features/{name}/

## Private Package Auth

`@packrat-ai/nativewindui` is hosted on GitHub Packages. The `preinstall` script (`configure-deps.ts`) automatically pulls your token from the GitHub CLI:
`@packrat-ai/nativewindui` is hosted on GitHub Packages. `bunfig.toml` resolves the scope using `$PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN`. Bun auto-loads `.env.local` before running `install`, so the simplest setup is to put the token there alongside your other secrets.

### One-time GitHub CLI setup

```bash
# One-time setup
gh auth login
gh auth refresh -h github.com -s read:packages
gh auth refresh -h github.com -s read:packages # write:packages also works
```

### Preferred: add the token to `.env.local`

Append to the repo-root `.env.local` (gitignored):

```bash
PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN=<token from `gh auth token`>
```

Then `bun install` just works β€” Bun picks it up automatically.

# Then bun install works β€” the preinstall script runs `gh auth token` automatically
### Alternative: export in shell

Useful in ephemeral shells or when you don't keep a `.env.local`:

```bash
# Inline
export PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN=$(gh auth token)
bun install

# One-liner
PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN=$(gh auth token) bun install
```

`bunfig.toml` references `$PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN`, which the preinstall script sets from `gh auth token` at install time.
The `preinstall` hook cannot inject env vars into the parent `bun install` process (Bun has already parsed `bunfig.toml`), so if neither `.env.local` nor a shell export has the token, install will 401.

### CI / environments without `gh`

Set the env var directly from secrets:

For CI or environments without `gh` CLI (e.g. Claude Code web), set the env var directly:
```bash
PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN=<token from `gh auth token`>
PACKRAT_NATIVEWIND_UI_GITHUB_TOKEN=<personal access token with read:packages>
```

If you get 401 errors during `bun install`, either `gh` isn't authenticated or the token is missing/expired.
### Troubleshooting

- **401 on `@packrat-ai/nativewindui`**: Token is missing from both `.env.local` and your shell, or lacks `read:packages`. Check `.env.local` first.
- The `preinstall` hook (`bun run configure:deps`) only *validates* that the token is visible to the install process β€” it doesn't inject it.

## Path Aliases

Expand Down
Loading