diff --git a/.github/workflows/create-prerelease-lexicon.yml b/.github/workflows/create-prerelease-lexicon.yml new file mode 100644 index 0000000..ed4fba7 --- /dev/null +++ b/.github/workflows/create-prerelease-lexicon.yml @@ -0,0 +1,71 @@ +name: Build and release - staging + +on: + workflow_dispatch: + inputs: + dry_run: + description: "Run in dry-run mode (test without publishing)" + required: false + default: false + type: boolean + +jobs: + release: + name: Release + runs-on: ubuntu-latest + environment: staging + permissions: + contents: write + id-token: write # to enable use of OIDC for npm provenance + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # fetch-depth: 0 means fetch full/unlimited git history (all commits, + # branches, tags). This is required for semantic-release to: + # 1. Find the last release tag (could be anywhere in history) + # 2. Analyze all commits since that tag to determine version bumps + # 3. Generate changelog entries from those commits + # Without full history, semantic-release cannot function correctly. + fetch-depth: 0 + persist-credentials: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Run lint + run: npm run lint + + - name: Prepare prerelease semantic + if: github.ref != 'refs/heads/main' + run: mv .releaserc.prerelease.yaml .releaserc.yaml + + - name: Semantic Release + uses: cycjimmy/semantic-release-action@v4 + id: semantic # Need an `id` for output variables + with: + dry_run: ${{ inputs.dry_run }} + extra_plugins: | + @semantic-release/commit-analyzer + @semantic-release/release-notes-generator + @semantic-release/changelog + @semantic-release/github + @semantic-release/npm + env: + GITHUB_TOKEN: ${{ secrets.GH_PA_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Do something when a new release published + if: steps.semantic.outputs.new_release_published == 'true' + run: | + echo ${{ steps.semantic.outputs.new_release_version }} + echo ${{ steps.semantic.outputs.new_release_major_version }} + echo ${{ steps.semantic.outputs.new_release_minor_version }} + echo ${{ steps.semantic.outputs.new_release_patch_version }} diff --git a/.github/workflows/create-release-lexicon.yml b/.github/workflows/create-release-lexicon.yml new file mode 100644 index 0000000..34d6911 --- /dev/null +++ b/.github/workflows/create-release-lexicon.yml @@ -0,0 +1,69 @@ +name: Build and release + +on: + workflow_dispatch: + inputs: + dry_run: + description: "Run in dry-run mode (test without publishing)" + required: false + default: false + type: boolean + +jobs: + release: + name: Release + runs-on: ubuntu-latest + environment: staging + permissions: + contents: write # to be able to publish a GitHub release + issues: write # to be able to comment on released issues + pull-requests: write # to be able to comment on released pull requests + id-token: write # to enable use of OIDC for npm provenance + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # fetch-depth: 0 means fetch full/unlimited git history (all commits, + # branches, tags). This is required for semantic-release to: + # 1. Find the last release tag (could be anywhere in history) + # 2. Analyze all commits since that tag to determine version bumps + # 3. Generate changelog entries from those commits + # Without full history, semantic-release cannot function correctly. + fetch-depth: 0 + persist-credentials: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Run lint + run: npm run lint + + - name: Semantic Release + uses: cycjimmy/semantic-release-action@v4 + id: semantic # Need an `id` for output variables + with: + dry_run: ${{ inputs.dry_run }} + extra_plugins: | + @semantic-release/commit-analyzer + @semantic-release/release-notes-generator + @semantic-release/changelog + @semantic-release/github + @semantic-release/npm + env: + GITHUB_TOKEN: ${{ secrets.GH_PA_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Do something when a new release published + if: steps.semantic.outputs.new_release_published == 'true' + run: | + echo ${{ steps.semantic.outputs.new_release_version }} + echo ${{ steps.semantic.outputs.new_release_major_version }} + echo ${{ steps.semantic.outputs.new_release_minor_version }} + echo ${{ steps.semantic.outputs.new_release_patch_version }} diff --git a/.github/workflows/dryrun-release-ci-lexicon.yml b/.github/workflows/dryrun-release-ci-lexicon.yml new file mode 100644 index 0000000..f37cd32 --- /dev/null +++ b/.github/workflows/dryrun-release-ci-lexicon.yml @@ -0,0 +1,55 @@ +name: Validate release (PR) + +on: + pull_request: + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + contents: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # fetch-depth: 0 means fetch full/unlimited git history (all commits, + # branches, tags). This is required for semantic-release to: + # 1. Find the last release tag (could be anywhere in history) + # 2. Analyze all commits since that tag to determine version bumps + # 3. Generate changelog entries from those commits + # Without full history, semantic-release cannot function correctly. + fetch-depth: 0 + persist-credentials: false + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Run lint + run: npm run lint + + - name: Prepare prerelease semantic + if: github.ref != 'refs/heads/main' + run: mv .releaserc.prerelease.yaml .releaserc.yaml + + - name: Semantic Release + uses: cycjimmy/semantic-release-action@v4 + id: semantic # Need an `id` for output variables + with: + dry_run: true + extra_plugins: | + @semantic-release/commit-analyzer + @semantic-release/release-notes-generator + @semantic-release/changelog + @semantic-release/github + @semantic-release/npm + env: + GITHUB_TOKEN: ${{ secrets.GH_PA_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.npmignore b/.npmignore index 51e5463..c48d51b 100644 --- a/.npmignore +++ b/.npmignore @@ -8,4 +8,3 @@ node_modules/ *.log results/ bun.lockb -lexicons/ \ No newline at end of file diff --git a/.releaserc.prerelease.yaml b/.releaserc.prerelease.yaml new file mode 100644 index 0000000..11188dc --- /dev/null +++ b/.releaserc.prerelease.yaml @@ -0,0 +1,12 @@ +plugins: + - "@semantic-release/commit-analyzer" + - "@semantic-release/release-notes-generator" + - "@semantic-release/changelog" + - "@semantic-release/github" + - "@semantic-release/npm" + +branches: + - "+([0-9])?(.{+([0-9]),x}).x" + - main + - name: develop + prerelease: "beta" diff --git a/.releaserc.yaml b/.releaserc.yaml new file mode 100644 index 0000000..c5578b5 --- /dev/null +++ b/.releaserc.yaml @@ -0,0 +1,10 @@ +plugins: + - "@semantic-release/commit-analyzer" + - "@semantic-release/release-notes-generator" + - "@semantic-release/changelog" + - "@semantic-release/github" + - "@semantic-release/npm" + +branches: + - "+([0-9])?(.{+([0-9]),x}).x" + - main diff --git a/PUBLISHING.md b/PUBLISHING.md new file mode 100644 index 0000000..7c5c60d --- /dev/null +++ b/PUBLISHING.md @@ -0,0 +1,89 @@ +# Publishing Guide for Maintainers + +This document describes how to publish the `@hypercerts-org/lexicon` +package to npm using GitHub Actions workflows. All publishing +workflows are manually triggered to give you full control over when +releases are made. + +## Prerequisites + +Before publishing, ensure you have: + +1. **GitHub Secrets configured:** + - `GH_PA_TOKEN`: GitHub Personal Access Token with permissions for + releases + - `NPM_TOKEN`: npm access token with publish permissions for + `@hypercerts-org` scope + +2. **GitHub Environments configured:** + - `test`: For the build-and-test job + - `staging`: For the semantic-release job + +## Publishing a Release + +To publish a new release to npm: + +1. **Navigate to GitHub Actions:** + - Go to the repository on GitHub + - Click on the "Actions" tab + +2. **Select the workflow:** + - Choose "Build and release" from the workflow list + +3. **Run the workflow:** + - Click "Run workflow" + - Select the branch (typically `main`) + - Click "Run workflow" to start + +4. **What happens:** + - The workflow runs linting and regenerates TypeScript types + - If successful, semantic-release analyzes your commits + - If there are version-worthy changes, it: + - Determines the new version based on + [Conventional Commits](https://www.conventionalcommits.org/) + - Updates `CHANGELOG.md` + - Creates a GitHub release + - Publishes to npm with the new version + +## Publishing a Prerelease + +To publish a beta/prerelease version: + +1. **Navigate to GitHub Actions:** + - Go to the "Actions" tab + +2. **Select the prerelease workflow:** + - Choose "Build and release - staging" + +3. **Run the workflow:** + - Click "Run workflow" + - Select the branch (typically `develop` or a feature branch) + - Click "Run workflow" + +4. **What happens:** + - Same process as above, but publishes with a `beta` tag + - Version format: `1.2.3-beta.1`, `1.2.3-beta.2`, etc. + +## Validating Releases (PRs) + +When you open a pull request, the "Build and release - staging" +workflow automatically runs in dry-run mode to: + +- Validate that the code builds successfully +- Check that types regenerate correctly +- Show what version would be released (without actually publishing) + +This helps catch issues before merging. + +## Version Management + +Versions are automatically determined by semantic-release based on +commit messages: + +- `feat:` → minor version bump (1.0.0 → 1.1.0) +- `fix:` → patch version bump (1.0.0 → 1.0.1) +- `BREAKING CHANGE:` or `!` → major version bump (1.0.0 → 2.0.0) + +The `prepublishOnly` script ensures types are regenerated before +publishing, so the published package always includes the latest +generated TypeScript types. diff --git a/README.md b/README.md index 1aaf3b2..25b2808 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ following icons: ## Installation -``` +```bash npm i @hypercerts-org/lexicon ``` diff --git a/package.json b/package.json index 5f94e5d..79b7226 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,15 @@ "version": "0.1.0", "description": "ATProto lexicon definitions and TypeScript types for the Hypercerts protocol", "type": "module", - "main": "./index.js", - "types": "./index.ts", + "main": "./types/index.ts", + "types": "./types/index.ts", "exports": { ".": { - "types": "./index.ts", - "import": "./index.ts" + "types": "./types/index.ts", + "import": "./types/index.ts" } }, "files": [ - "index.ts", "types", "lexicons" ],