1.8.0 #11
Workflow file for this run
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: Build and Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" # Triggers on tags like v1.0.0, v1.2.3, etc. | |
| workflow_dispatch: # Allows manual triggering for testing workflow only | |
| inputs: | |
| dry_run: | |
| description: "Run validation without creating release" | |
| required: false | |
| default: "true" | |
| type: boolean | |
| jobs: | |
| # Validation job - runs on both tag push and manual trigger | |
| validate: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| outputs: | |
| version: ${{ steps.get_version.outputs.version }} | |
| is_tag: ${{ steps.check_trigger.outputs.is_tag }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check trigger type | |
| id: check_trigger | |
| run: | | |
| if [[ "${{ github.ref }}" == refs/tags/v* ]]; then | |
| echo "is_tag=true" >> $GITHUB_OUTPUT | |
| echo "Triggered by tag push" | |
| else | |
| echo "is_tag=false" >> $GITHUB_OUTPUT | |
| echo "Triggered manually - validation only" | |
| fi | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build project | |
| run: npm run build | |
| - name: Verify build artifacts exist | |
| run: | | |
| echo "Checking for required build artifacts..." | |
| if [ ! -d "dist" ]; then | |
| echo "❌ Error: dist directory not found" | |
| exit 1 | |
| fi | |
| if [ ! -f "dist/index.js" ]; then | |
| echo "❌ Error: dist/index.js not found" | |
| exit 1 | |
| fi | |
| if [ ! -d "dist/types" ]; then | |
| echo "❌ Error: dist/types directory not found" | |
| exit 1 | |
| fi | |
| if [ ! -f "dist/types/index.d.ts" ]; then | |
| echo "❌ Error: dist/types/index.d.ts not found" | |
| exit 1 | |
| fi | |
| echo "✅ All build artifacts verified successfully" | |
| - name: Extract version from tag | |
| id: get_version | |
| run: | | |
| if [[ "${{ github.ref }}" == refs/tags/v* ]]; then | |
| VERSION=${GITHUB_REF#refs/tags/v} | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Extracted version from tag: $VERSION" | |
| else | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "Extracted version from package.json: $VERSION" | |
| fi | |
| - name: Verify package.json version matches tag | |
| if: startsWith(github.ref, 'refs/tags/') | |
| run: | | |
| PACKAGE_VERSION=$(node -p "require('./package.json').version") | |
| TAG_VERSION="${{ steps.get_version.outputs.version }}" | |
| echo "Package version: $PACKAGE_VERSION" | |
| echo "Tag version: $TAG_VERSION" | |
| if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then | |
| echo "❌ Error: package.json version ($PACKAGE_VERSION) doesn't match tag version ($TAG_VERSION)" | |
| echo "Please update package.json version to match the tag or create a new tag matching package.json" | |
| exit 1 | |
| fi | |
| echo "✅ Version verification passed" | |
| - name: Verify package.json configuration | |
| run: | | |
| echo "Verifying package.json configuration..." | |
| MAIN=$(node -p "require('./package.json').main") | |
| if [ "$MAIN" != "dist/index.js" ]; then | |
| echo "⚠️ Warning: main entry point is '$MAIN', expected 'dist/index.js'" | |
| fi | |
| TYPES=$(node -p "require('./package.json').types") | |
| if [ "$TYPES" != "dist/types/index.d.ts" ]; then | |
| echo "⚠️ Warning: types entry point is '$TYPES', expected 'dist/types/index.d.ts'" | |
| fi | |
| FILES=$(node -p "JSON.stringify(require('./package.json').files || [])") | |
| echo "Package includes files: $FILES" | |
| echo "✅ Package configuration verified" | |
| # Release job - only runs on tag push (not on manual trigger) | |
| release: | |
| needs: validate | |
| if: needs.validate.outputs.is_tag == 'true' && startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| cache: "npm" | |
| - name: Install dependencies | |
| run: npm ci | |
| - name: Build project | |
| run: npm run build | |
| - name: Verify build artifacts | |
| run: | | |
| echo "Verifying build artifacts..." | |
| if [ ! -d "dist" ] || [ ! -f "dist/index.js" ] || [ ! -f "dist/types/index.d.ts" ]; then | |
| echo "❌ Build artifacts missing" | |
| exit 1 | |
| fi | |
| echo "✅ Build artifacts verified" | |
| - name: Configure Git | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| - name: Add built artifacts to tag | |
| run: | | |
| TAG_NAME=${GITHUB_REF#refs/tags/} | |
| echo "Adding built artifacts to tag: $TAG_NAME" | |
| # Add built artifacts (force add despite .gitignore) | |
| git add -f dist/ | |
| # Commit the built artifacts | |
| git commit -m "chore: add built artifacts for $TAG_NAME" \ | |
| -m "Auto-generated by GitHub Actions workflow." \ | |
| -m "Built from commit: ${{ github.sha }}" | |
| # Delete the old tag locally | |
| git tag -d $TAG_NAME | |
| # Create new tag with built artifacts | |
| git tag $TAG_NAME | |
| # TECH DEBT: Force push is required here because: | |
| # 1. The tag is created by `npm run release:*` before the workflow runs | |
| # 2. We need to update that tag to include built artifacts (dist/) | |
| # 3. Git doesn't allow updating tags without force push (immutability by design) | |
| # 4. This is safe because it happens immediately in CI before anyone fetches the tag | |
| # 5. Alternative would be npm registry, but we're doing GitHub-only distribution | |
| # Trade-off: Pragmatic solution for GitHub package distribution vs strict git best practices | |
| git push origin $TAG_NAME --force | |
| echo "✅ Tag $TAG_NAME updated with built artifacts" | |
| - name: Update release branch with built artifacts | |
| run: | | |
| TAG_NAME=${GITHUB_REF#refs/tags/} | |
| echo "Updating release branch to point to: $TAG_NAME" | |
| # Fetch all branches and tags | |
| git fetch origin | |
| # Delete local release branch if it exists | |
| git branch -D release 2>/dev/null || true | |
| # Create new release branch from current commit (which has dist/) | |
| echo "Creating release branch..." | |
| git checkout -b release | |
| # Delete remote release branch if it exists | |
| echo "Deleting old release branch on remote (if exists)..." | |
| git push origin --delete release 2>/dev/null || echo "No existing release branch to delete" | |
| # Push the new release branch | |
| echo "Pushing release branch..." | |
| git push origin release | |
| echo "✅ Release branch updated successfully" | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: Release v${{ needs.validate.outputs.version }} | |
| tag_name: ${{ github.ref_name }} | |
| body: | | |
| ## 🚀 Release v${{ needs.validate.outputs.version }} | |
| ### 📦 Installation | |
| #### Option 1: Use release branch (auto-updates to latest release) | |
| Add to your `package.json`: | |
| ```json | |
| { | |
| "dependencies": { | |
| "github-release-consumer": "github:${{ github.repository }}#release" | |
| } | |
| } | |
| ``` | |
| #### Option 2: Pin to specific version (recommended for production) | |
| Add to your `package.json`: | |
| ```json | |
| { | |
| "dependencies": { | |
| "github-release-consumer": "github:${{ github.repository }}#v${{ needs.validate.outputs.version }}" | |
| } | |
| } | |
| ``` | |
| Then run: | |
| ```bash | |
| npm install | |
| # or | |
| pnpm install | |
| # or | |
| yarn install | |
| ``` | |
| ### 🔧 How it works | |
| - Pre-built artifacts are included in the tag and release branch | |
| - **No build required** during installation - fast and efficient! | |
| - Works perfectly in CI/CD environments (no `npm ci` slowdown) | |
| - TypeScript types and source maps are pre-generated | |
| ### 📋 What's included | |
| - ✅ Build validated and verified | |
| - ✅ Pre-built JavaScript bundles | |
| - ✅ TypeScript type definitions | |
| - ✅ Source maps for debugging | |
| - ✅ Zero build overhead for consumers | |
| ### ⚡ Performance | |
| Installing from GitHub with pre-built artifacts is: | |
| - 🚀 **Faster** - No compilation needed | |
| - 💾 **Lighter** - No devDependencies required | |
| - 🔒 **Safer** - No build scripts executed during install | |
| --- | |
| *Generated automatically by GitHub Actions* | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |