# CI/CD Pipeline Setup

This repository uses GitHub Actions for continuous integration and deployment.

## Workflows

### 1. CI Workflow (`ci.yml`)
- Runs on pull requests and pushes to main/master
- Builds the package to ensure it compiles correctly
- Does not publish to npm

### 2. Publish Workflow (`publish.yml`)
- Runs on pushes to main/master branch
- Runs on version tags (e.g., `v1.0.0`)
- Can be manually triggered from GitHub Actions UI
- Builds and publishes the package to npm

## Setup Instructions

### 1. Verify npm Organization/Scope Access

**Important**: For scoped packages like `@cqa-lib/cqa-ui`, you need to ensure:

1. **If `@cqa-lib` is an npm organization:**
   - You must be a member of the `@cqa-lib` organization
   - You must have publish permissions for the organization
   - Go to [npmjs.com/org/cqa-lib](https://www.npmjs.com/org/cqa-lib) to verify membership

2. **If `@cqa-lib` is your personal scope:**
   - Make sure you're logged into the correct npm account
   - The package name matches your npm username/scope

3. **First-time publish:**
   - If the package doesn't exist yet, npm will create it
   - Make sure you have permission to create packages in the scope

### 2. Create NPM Granular Token

1. Go to [npmjs.com/settings/~/tokens](https://www.npmjs.com/settings/~/tokens)
2. Click "Generate New Token" → "Granular Access Token"
3. Configure the token:
   - **Token name**: `cqa-ui-lib-ci` (or any descriptive name)
   - **Expiration**: 90 days (maximum for write tokens)
   - **Type**: Automation
   - **Packages**: 
     - If `@cqa-lib` is an org: Select `@cqa-lib/cqa-ui` specifically
     - If personal scope: Select "All packages" or your scope
   - **Permissions**: Read and write
   - **Bypass 2FA**: Enable this for non-interactive CI/CD workflows

4. Copy the token (you won't be able to see it again!)

### 2. Add Secret to GitHub Repository

1. Go to your GitHub repository
2. Navigate to **Settings** → **Secrets and variables** → **Actions**
3. Click **New repository secret**
4. **Name: `NODE_AUTH_TOKEN`** (Important: Must be exactly `NODE_AUTH_TOKEN` for `setup-node` action)
5. Value: Paste your granular token
6. Click **Add secret**

**Note**: The secret must be named `NODE_AUTH_TOKEN` (not `NPM_TOKEN`) because the `actions/setup-node` action automatically uses this secret name when `registry-url` is provided.

### 3. Publishing Options

#### Option A: Auto-publish on commits to main/master
- Every push to main/master will trigger a publish
- Make sure to bump the version in `package.json` before committing

#### Option B: Publish on version tags (Recommended)
1. Update version in `package.json`
2. Commit and push:
   ```bash
   git add package.json
   git commit -m "chore: bump version to 1.0.85"
   git push
   ```
3. Create and push a version tag:
   ```bash
   git tag v1.0.85
   git push origin v1.0.85
   ```
4. The workflow will automatically publish and create a GitHub release

#### Option C: Manual publish
- Go to **Actions** tab in GitHub
- Select **Publish to npm** workflow
- Click **Run workflow**
- Select branch and click **Run workflow**

## Important Notes

- **Token Expiration**: Granular tokens expire after 90 days. You'll need to regenerate and update the secret.
- **2FA**: If you have 2FA enabled on your npm account, make sure to enable "Bypass 2FA" when creating the token for CI/CD.
- **Version Management**: Always update the version in `package.json` before publishing.
- **OIDC Alternative**: For more secure publishing, consider setting up [OIDC trusted publishing](https://docs.npmjs.com/about-oidc-trusted-publishing) which eliminates the need for tokens.

## Troubleshooting

### "401 Unauthorized" or "Authentication failed"

**Step 1: Verify Secret Exists**
1. Go to your GitHub repository
2. Navigate to **Settings** → **Secrets and variables** → **Actions**
3. Look for a secret named exactly `NODE_AUTH_TOKEN` (case-sensitive)
4. If it doesn't exist or is named differently, create/rename it

**Step 2: Verify Token is Valid**
1. Go to [npmjs.com/settings/~/tokens](https://www.npmjs.com/settings/~/tokens)
2. Check if your token exists and hasn't expired
3. If expired or missing, create a new granular token:
   - Click "Generate New Token" → "Granular Access Token"
   - Name: `cqa-ui-lib-ci`
   - Expiration: 90 days
   - Type: Automation
   - Packages: `@cqa-lib/cqa-ui` or "All packages"
   - Permissions: Read and write
   - **Enable "Bypass 2FA"** for CI/CD
4. Copy the new token and update the `NODE_AUTH_TOKEN` secret in GitHub

**Step 3: Verify Token Permissions**
- Make sure the token has **write** permissions (not just read)
- If using an organization scope (`@cqa-lib`), ensure you're a member with publish permissions
- Test the token locally:
  ```bash
  export NPM_TOKEN="your-token-here"
  echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
  npm whoami  # Should print your npm username
  ```

**Step 4: Check Workflow Logs**
- Look at the "Verify npm authentication setup" step in the workflow logs
- It will show if the token is set and its length
- If it shows "Token is set (length: 0 characters)", the secret is empty

### "404 Not Found" when publishing
This error typically means one of the following:

1. **Package doesn't exist yet (first publish):**
   - This is normal for the first publish
   - Make sure you have permission to create packages in the `@cqa-lib` scope
   - Verify you're a member of the `@cqa-lib` organization (if it's an org)

2. **No access to the scope:**
   - Check if `@cqa-lib` is an organization you're a member of
   - Verify your npm account has publish permissions
   - Try running `npm whoami` locally to verify your npm identity

3. **Token permissions:**
   - Ensure the granular token has "Read and write" permissions
   - Make sure the token is scoped to `@cqa-lib/cqa-ui` or "All packages"
   - Verify "Bypass 2FA" is enabled for automation tokens

4. **Package name mismatch:**
   - Ensure the package name in `package.json` matches exactly: `@cqa-lib/cqa-ui`
   - Check that `publishConfig.access` is set to `public` in `package.json`

### "You do not have permission to publish"
- Verify you're a member of the `@cqa-lib` organization
- Check organization settings for publish permissions
- Ensure your npm account has the correct role (admin/maintainer)

### Test locally first
Before relying on CI/CD, test publishing locally:
```bash
# Set your token
export NPM_TOKEN="your-token-here"
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc

# Build and publish
npm run build:cqa-ui
cd dist/cqa-ui
npm publish --access public --dry-run  # Test without publishing
npm publish --access public            # Actual publish
```

### Build fails
- Check Node.js version matches (16.20.2)
- Verify all dependencies are installed correctly
- Review build logs in GitHub Actions

