diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml new file mode 100644 index 0000000..c2ff5bf --- /dev/null +++ b/.github/workflows/pr-build.yml @@ -0,0 +1,38 @@ +# PR Build — Generate VSIX artifact for manual testing +# Triggers on every pull request to main. +# Produces a .vsix file uploaded as a build artifact +# so reviewers can download and install it in VS Code. + +name: PR Build — VSIX + +on: + pull_request: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Package VSIX + run: npm run package + + - name: Upload VSIX artifact + uses: actions/upload-artifact@v4 + with: + name: hermes-vscode-vsix + path: hermes-*.vsix + retention-days: 14 + if-no-files-found: error diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ad65be8 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,68 @@ +# Release — Build and package to GitHub Releases +# Triggers on push to main. +# Produces a .vsix, creates a GitHub Release with the artifact attached. + +name: Release + +on: + push: + branches: [main] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: write # for creating GitHub Releases + packages: write # for GitHub Packages (if used later) + attestations: write # for artifact attestation + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Package VSIX + run: npm run package + + # Extract version from package.json for release tag + - name: Extract version + id: version + run: echo "tag=v$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT + + # Fail if version tag already exists + - name: Check if version tag exists + run: | + tag="${{ steps.version.outputs.tag }}" + if git ls-remote --exit-code --tags origin "refs/tags/$tag" > /dev/null 2>&1; then + echo "Error: Version tag $tag already exists" + exit 1 + fi + + # Upload VSIX as an artifact (for archival) + - name: Upload VSIX artifact + uses: actions/upload-artifact@v4 + with: + name: hermes-vscode-vsix + path: hermes-*.vsix + retention-days: 90 + if-no-files-found: error + + # Create GitHub Release with VSIX attached + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.version.outputs.tag }} + name: Hermes VS Code ${{ steps.version.outputs.tag }} + files: hermes-*.vsix + generate_release_notes: true + fail_on_unmatched_files: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CI-SETUP.md b/CI-SETUP.md new file mode 100644 index 0000000..63552e8 --- /dev/null +++ b/CI-SETUP.md @@ -0,0 +1,107 @@ +# CI/CD Setup for hermes-vscode + +This document describes the GitHub Actions workflows and required secrets. + +## Workflows + +### 1. PR Build (`.github/workflows/pr-build.yml`) + +- Triggers on every pull request to `main`. +- Runs on `ubuntu-latest`. +- Steps: + - Checkout + - Setup Node.js 20 (with npm cache) + - `npm ci` (clean install) + - `npm run build` (webpack production) + - `npm run package` (vsce package → `.vsix`) + - Upload VSIX as a build artifact (retained 14 days) + +**Purpose:** Provide PR reviewers with a downloadable VSIX to manually install and test the extension. + +Artifact name: `hermes-vscode-vsix` (download from the PR's "Artifacts" section). + +--- + +### 2. Release (`.github/workflows/release.yml`) + +- Triggers on push to `main`. +- Runs on `ubuntu-latest`. +- Permissions: `contents: write`, `packages: write`, `attestations: write`. +- Steps: + - Same build/packaging steps as PR + - Extract version from `package.json` → `vX.Y.Z` + - Upload VSIX as artifact (retained 90 days) + - **Always** create a GitHub Release with that tag and attach the VSIX + +Warning: Before pushing to `main`, make sure `package.json`'s `version` has been bumped if you expect a new release. The workflow derives the release tag directly from that version, so pushing again with the same version will try to reuse the existing `vX.Y.Z` tag/release. In that case, the release step will typically fail or create a noisy duplicate-release attempt rather than producing a new versioned release. + +Note: Automatic publishing to the VS Code Marketplace is **not** configured. If you want CI to publish to the marketplace, add a step and the `VSCE_TOKEN` secret. + +--- + +## Secrets Configuration + +Add these secrets in **GitHub Repo Settings → Secrets and variables → Actions**: + +| Secret | Required? | Description | +|--------|-----------|-------------| +| `GITHUB_TOKEN` | No (auto-provided) | Automatically provided by GitHub Actions. Used for creating GitHub Releases. No manual setup needed. | + +No other secrets are required for the current CI configuration. + +--- + +## Manual Publishing to VS Code Marketplace (Optional) + +If you want to publish manually: + +1. Run locally: `npm run publish` (requires `VSCE_TOKEN` in env) +2. To get a token: https://aka.ms/vscode-vsce +3. Set env var: `VSCE_TOKEN=your_token npm run publish` + +Or add a marketplace publish step back into `release.yml` if desired. + +--- + +## Manual Testing from PR Artifacts + +1. Open the PR on GitHub. +2. In the "Checks" section, find the "PR Build — VSIX" workflow. +3. Click "Artifacts" → download `hermes-vscode-vsix.zip`. +4. Extract `.vsix` file. +5. In VS Code: Extensions view → `...` → "Install from VSIX..." → select the file. +6. Verify functionality. + +--- + +## Version Bumping + +Before merging a PR that should be a new release, bump the `version` in `package.json`. The release workflow reads that version to create both: +- The GitHub release tag (`v3.0.0`, `v3.1.0`, etc.) +- The attached VSIX filename (`hermes-ai-agent-3.0.0.vsix`) + +Follow semantic versioning: +- Patch: bugfixes only (x.y.Z) +- Minor: new features (x.Y.0) +- Major: breaking changes (X.0.0) + +--- + +## Troubleshooting + +**Workflow fails at `npm ci`?** +- Check `package-lock.json` is present and up-to-date. If not, run `npm install` locally and commit the updated lockfile. + +**VSIX artifact not generated?** +- Ensure `npm run package` completes successfully. The script uses `vsce package --no-dependencies`. The `@vscode/vsce` dependency is in `devDependencies` and will be installed by `npm ci`. + +**Release creation fails?** +- Verify the `GITHUB_TOKEN` has `contents: write` permission (default in most repos). The workflow sets `permissions` appropriately. + +--- + +## Notes + +- The workflows do not run on forks unless the fork's Actions are enabled. +- Because we use `upload-artifact` on PRs, artifacts are stored for 14 days. GitHub retention limits apply depending on your plan. +- If you later decide to publish to the VS Code Marketplace via CI, add the `VSCE_TOKEN` secret and a publish step analogous to the one previously provided. diff --git a/package.json b/package.json index a45dd89..9e74a1b 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,8 @@ "vscode:prepublish": "npm run build", "build": "webpack --mode production", "dev": "webpack --mode development --watch", - "package": "vsce package --no-dependencies" + "package": "vsce package --no-dependencies", + "vsce:publish": "vsce publish --no-dependencies" }, "devDependencies": { "@types/dompurify": "^3.0.5",