chore: adjust install and build release #29
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: Release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| workflow_dispatch: | |
| # Prevent multiple concurrent releases - only one release workflow should run at a time | |
| # If a new push happens during a release, cancel the old one and start the new one | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false # Don't cancel releases - queue them instead for safety | |
| permissions: | |
| contents: write | |
| packages: write | |
| jobs: | |
| # Run full test suite first | |
| test: | |
| name: Test Suite | |
| uses: ./.github/workflows/test.yml | |
| # Run security audit | |
| security: | |
| name: Security Audit | |
| uses: ./.github/workflows/security.yml | |
| permissions: | |
| actions: read | |
| contents: read | |
| security-events: write | |
| # Create draft GitHub release | |
| create-draft-release: | |
| name: Create Draft Release | |
| needs: [test, security] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| outputs: | |
| release-id: ${{ steps.create-release.outputs.id }} | |
| upload-url: ${{ steps.create-release.outputs.upload_url }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get version from package.json | |
| id: package-version | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=v$VERSION" >> $GITHUB_OUTPUT | |
| - name: Create Draft Release | |
| id: create-release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.package-version.outputs.tag }} | |
| name: Release ${{ steps.package-version.outputs.tag }} | |
| body: | | |
| ## Installation | |
| ### Using installers (Recommended) | |
| **Unix (macOS/Linux)**: | |
| ```bash | |
| curl -fsSL https://raw.githubusercontent.com/codedir-labs/mimir-code/main/scripts/install.sh | bash | |
| ``` | |
| **Windows (PowerShell)**: | |
| ```powershell | |
| irm https://raw.githubusercontent.com/codedir-labs/mimir-code/main/scripts/install.ps1 | iex | |
| ``` | |
| ### Using npm | |
| ```bash | |
| npm install -g @codedir/mimir-code | |
| ``` | |
| Or with yarn: | |
| ```bash | |
| yarn global add @codedir/mimir-code | |
| ``` | |
| ### Manual Installation | |
| Download the archive for your platform from the Assets section below and extract it to a directory in your PATH. | |
| draft: true | |
| prerelease: false | |
| generate_release_notes: true | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Output release info | |
| run: | | |
| echo "Created draft release:" | |
| echo " ID: ${{ steps.create-release.outputs.id }}" | |
| echo " Tag: ${{ steps.package-version.outputs.tag }}" | |
| echo " URL: ${{ steps.create-release.outputs.url }}" | |
| # Build distribution packages (tar.gz/zip) for all platforms | |
| build-binaries: | |
| name: Build Distribution Packages | |
| needs: create-draft-release | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v1 | |
| with: | |
| bun-version: latest | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: 'yarn' | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Build TypeScript | |
| run: yarn build | |
| - name: Clean old binaries | |
| run: rm -rf dist/binaries && mkdir -p dist/binaries | |
| - name: Build distribution packages | |
| run: yarn build:binary:all | |
| - name: List distribution packages | |
| run: ls -lah dist/binaries/ || echo "No binaries directory found" | |
| - name: Get version from package.json | |
| id: package-version | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| - name: Verify distribution packages were created | |
| run: | | |
| VERSION="${{ steps.package-version.outputs.version }}" | |
| EXPECTED_PACKAGES=( | |
| "mimir-code-v${VERSION}-linux-amd64.tar.gz" | |
| "mimir-code-v${VERSION}-darwin-amd64.tar.gz" | |
| "mimir-code-v${VERSION}-darwin-arm64.tar.gz" | |
| "mimir-code-v${VERSION}-windows-amd64.zip" | |
| ) | |
| MISSING_COUNT=0 | |
| for package in "${EXPECTED_PACKAGES[@]}"; do | |
| if [ -f "dist/binaries/$package" ]; then | |
| echo "β Found: $package" | |
| # Show package size | |
| du -h "dist/binaries/$package" | |
| else | |
| echo "β Missing: $package" | |
| MISSING_COUNT=$((MISSING_COUNT + 1)) | |
| fi | |
| done | |
| if [ $MISSING_COUNT -gt 0 ]; then | |
| echo "" | |
| echo "Error: $MISSING_COUNT package(s) missing" | |
| echo "Directory contents:" | |
| ls -lah dist/binaries/ | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "β All distribution packages created successfully" | |
| - name: Upload distribution packages to release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: v${{ steps.package-version.outputs.version }} | |
| files: | | |
| dist/binaries/mimir-code-v${{ steps.package-version.outputs.version }}-linux-amd64.tar.gz | |
| dist/binaries/mimir-code-v${{ steps.package-version.outputs.version }}-darwin-amd64.tar.gz | |
| dist/binaries/mimir-code-v${{ steps.package-version.outputs.version }}-darwin-arm64.tar.gz | |
| dist/binaries/mimir-code-v${{ steps.package-version.outputs.version }}-windows-amd64.zip | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Test installation from draft release on all platforms | |
| test-draft-installation: | |
| name: Test Installation - ${{ matrix.name }} | |
| needs: [create-draft-release, build-binaries] | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false # Run all tests even if one fails | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| name: Linux | |
| shell: bash | |
| config_path: ~/.mimir/config.yml | |
| install_script: scripts/install.sh | |
| uninstall_script: scripts/uninstall.sh | |
| - os: macos-latest | |
| name: macOS | |
| shell: bash | |
| config_path: ~/.mimir/config.yml | |
| install_script: scripts/install.sh | |
| uninstall_script: scripts/uninstall.sh | |
| - os: windows-latest | |
| name: Windows | |
| shell: pwsh | |
| config_path: $env:USERPROFILE\.mimir\config.yml | |
| install_script: scripts\install.ps1 | |
| uninstall_script: scripts\uninstall.ps1 | |
| defaults: | |
| run: | |
| shell: ${{ matrix.shell }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get version from package.json | |
| id: package-version | |
| shell: bash | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=v$VERSION" >> $GITHUB_OUTPUT | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: 'npm' | |
| - name: Test installation (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| # Test the curl | bash installation method | |
| curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.sh | bash -s -- "${{ steps.package-version.outputs.tag }}" "true" | |
| - name: Test installation (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| # Test the iwr | iex installation method | |
| Invoke-WebRequest -Uri "https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.ps1" -OutFile "$env:TEMP\install.ps1" | |
| & "$env:TEMP\install.ps1" -Version "${{ steps.package-version.outputs.tag }}" -TestMode | |
| Remove-Item "$env:TEMP\install.ps1" | |
| - name: Test upgrade scenario (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Testing upgrade scenario..." | |
| # Modify config to test preservation | |
| echo "# Custom user setting" >> ~/.mimir/config.yml | |
| echo "customTest: true" >> ~/.mimir/config.yml | |
| # Run installation again (simulating upgrade) | |
| bash scripts/install.sh ${{ steps.package-version.outputs.tag }} false | |
| # Verify config was preserved | |
| if grep -q "customTest" ~/.mimir/config.yml; then | |
| echo "β User config preserved during upgrade" | |
| else | |
| echo "β User config was overwritten" | |
| exit 1 | |
| fi | |
| - name: Test upgrade scenario (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing upgrade scenario..." | |
| # Modify config to test preservation | |
| Add-Content -Path "$env:USERPROFILE\.mimir\config.yml" -Value "# Custom user setting" | |
| Add-Content -Path "$env:USERPROFILE\.mimir\config.yml" -Value "customTest: true" | |
| # Run installation again (simulating upgrade) | |
| & scripts\install.ps1 -Version ${{ steps.package-version.outputs.tag }} | |
| # Verify config was preserved | |
| $configContent = Get-Content "$env:USERPROFILE\.mimir\config.yml" -Raw | |
| if ($configContent -match "customTest") { | |
| Write-Host "β User config preserved during upgrade" | |
| } else { | |
| Write-Host "β User config was overwritten" | |
| exit 1 | |
| } | |
| - name: Test uninstall script (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Testing uninstall..." | |
| # Make uninstall script executable | |
| chmod +x scripts/uninstall.sh | |
| # Run uninstall (simulate keeping config) | |
| echo "N" | bash scripts/uninstall.sh || true | |
| # Config should still exist | |
| if [ -d "$HOME/.mimir" ]; then | |
| echo "β Config preserved when requested" | |
| else | |
| echo "β Config was removed unexpectedly" | |
| exit 1 | |
| fi | |
| # Run uninstall again (simulate removing config) | |
| echo -e "Y\nN" | bash scripts/uninstall.sh || true | |
| # Config should be backed up and removed | |
| if [ ! -d "$HOME/.mimir" ]; then | |
| echo "β Config removed when requested" | |
| else | |
| echo "β Config still exists" | |
| exit 1 | |
| fi | |
| - name: Test uninstall script (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing uninstall..." | |
| # For Windows, verify the uninstall script exists | |
| if (Test-Path "scripts\uninstall.ps1") { | |
| Write-Host "β Uninstall script exists" | |
| } else { | |
| Write-Host "β Uninstall script not found" | |
| exit 1 | |
| } | |
| - name: Create test summary | |
| if: success() | |
| run: | | |
| echo "β All tests passed on ${{ matrix.name }}" >> $GITHUB_STEP_SUMMARY | |
| echo " - Installation test passed" >> $GITHUB_STEP_SUMMARY | |
| echo " - Upgrade test passed" >> $GITHUB_STEP_SUMMARY | |
| echo " - Uninstall test passed" >> $GITHUB_STEP_SUMMARY | |
| # Publish GitHub release only after successful installation tests | |
| publish-github-release: | |
| name: Publish GitHub Release | |
| needs: [create-draft-release, test-draft-installation] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Publish GitHub Release | |
| uses: actions/github-script@v7 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| script: | | |
| const releaseId = '${{ needs.create-draft-release.outputs.release-id }}'; | |
| // Publish the draft release | |
| await github.rest.repos.updateRelease({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| release_id: releaseId, | |
| draft: false | |
| }); | |
| console.log(`Published release ${releaseId}`); | |
| core.summary.addRaw('β GitHub Release published successfully!'); | |
| await core.summary.write(); | |
| # Publish to npm after GitHub release is public | |
| publish-npm: | |
| name: Publish to npm | |
| needs: publish-github-release | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| id-token: write # Required for npm Trusted Publishers (OIDC) | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get version from package.json | |
| id: package-version | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=v$VERSION" >> $GITHUB_OUTPUT | |
| - name: Setup Node.js for npm publish | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| registry-url: 'https://registry.npmjs.org' | |
| cache: 'yarn' | |
| - name: Upgrade npm for Trusted Publishers | |
| run: npm install -g npm@latest | |
| - name: Verify npm version | |
| run: npm --version | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Build for npm | |
| run: yarn build | |
| - name: Publish to npm (Trusted Publishers / OIDC) | |
| run: npm publish --provenance --access public | |
| - name: Create publish summary | |
| run: | | |
| echo "## npm Package Published! π¦" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Version**: ${{ steps.package-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Package**: https://www.npmjs.com/package/@codedir/mimir-code" >> $GITHUB_STEP_SUMMARY | |
| # Deploy documentation after npm publish | |
| deploy-docs: | |
| name: Deploy Documentation | |
| needs: publish-npm | |
| uses: ./.github/workflows/deploy-docs.yml | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| # Test installation from npm on all platforms | |
| test-npm-installation: | |
| name: Test npm Installation - ${{ matrix.name }} | |
| needs: publish-npm | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false # Run all tests even if one fails | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| name: Linux | |
| shell: bash | |
| - os: macos-latest | |
| name: macOS | |
| shell: bash | |
| - os: windows-latest | |
| name: Windows | |
| shell: pwsh | |
| defaults: | |
| run: | |
| shell: ${{ matrix.shell }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: 'npm' | |
| - name: Wait for npm package to be available (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Waiting for npm package to be available..." | |
| sleep 60 | |
| - name: Wait for npm package to be available (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Waiting for npm package to be available..." | |
| Start-Sleep -Seconds 60 | |
| - name: Test npm installation (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| # Test the curl | bash installation method | |
| curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.sh | bash -s -- "latest" "true" | |
| - name: Test npm installation (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| # Download and execute installation script | |
| Invoke-WebRequest -Uri "https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.ps1" -OutFile "$env:TEMP\install.ps1" | |
| & "$env:TEMP\install.ps1" -Version "latest" -TestMode | |
| Remove-Item "$env:TEMP\install.ps1" | |
| - name: Test upgrade scenario (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Testing npm upgrade scenario..." | |
| # Modify config to test preservation | |
| echo "# Custom user setting" >> ~/.mimir/config.yml | |
| echo "customTest: true" >> ~/.mimir/config.yml | |
| # Run installation again (simulating upgrade) | |
| curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.sh | bash -s -- "latest" "false" | |
| # Verify config was preserved | |
| if grep -q "customTest" ~/.mimir/config.yml; then | |
| echo "β User config preserved during npm upgrade" | |
| else | |
| echo "β User config was overwritten" | |
| exit 1 | |
| fi | |
| - name: Test upgrade scenario (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing npm upgrade scenario..." | |
| # Modify config to test preservation | |
| Add-Content -Path "$env:USERPROFILE\.mimir\config.yml" -Value "# Custom user setting" | |
| Add-Content -Path "$env:USERPROFILE\.mimir\config.yml" -Value "customTest: true" | |
| # Run installation again (simulating upgrade) | |
| Invoke-WebRequest -Uri "https://raw.githubusercontent.com/${{ github.repository }}/main/scripts/install.ps1" -OutFile "$env:TEMP\install.ps1" | |
| & "$env:TEMP\install.ps1" -Version "latest" | |
| Remove-Item "$env:TEMP\install.ps1" | |
| # Verify config was preserved | |
| $configContent = Get-Content "$env:USERPROFILE\.mimir\config.yml" -Raw | |
| if ($configContent -match "customTest") { | |
| Write-Host "β User config preserved during npm upgrade" | |
| } else { | |
| Write-Host "β User config was overwritten" | |
| exit 1 | |
| } | |
| - name: Test uninstall script (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Testing uninstall..." | |
| # Make uninstall script executable | |
| chmod +x scripts/uninstall.sh | |
| # Run uninstall (simulate keeping config) | |
| echo "N" | bash scripts/uninstall.sh || true | |
| # Config should still exist | |
| if [ -d "$HOME/.mimir" ]; then | |
| echo "β Config preserved when requested" | |
| else | |
| echo "β Config was removed unexpectedly" | |
| exit 1 | |
| fi | |
| # Run uninstall again (simulate removing config) | |
| echo -e "Y\nN" | bash scripts/uninstall.sh || true | |
| # Config should be backed up and removed | |
| if [ ! -d "$HOME/.mimir" ]; then | |
| echo "β Config removed when requested" | |
| else | |
| echo "β Config still exists" | |
| exit 1 | |
| fi | |
| - name: Test uninstall script (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing uninstall..." | |
| # For Windows, verify the uninstall script exists | |
| if (Test-Path "scripts\uninstall.ps1") { | |
| Write-Host "β Uninstall script exists" | |
| } else { | |
| Write-Host "β Uninstall script not found" | |
| exit 1 | |
| } | |
| - name: Create test summary | |
| if: success() | |
| run: | | |
| echo "β All npm tests passed on ${{ matrix.name }}" >> $GITHUB_STEP_SUMMARY | |
| echo " - npm installation test passed" >> $GITHUB_STEP_SUMMARY | |
| echo " - Upgrade test passed" >> $GITHUB_STEP_SUMMARY | |
| echo " - Uninstall test passed" >> $GITHUB_STEP_SUMMARY | |
| # Final release summary | |
| release-complete: | |
| name: Release Complete | |
| needs: [publish-npm, deploy-docs, test-npm-installation] | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Get version from package.json | |
| id: package-version | |
| run: | | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=v$VERSION" >> $GITHUB_OUTPUT | |
| - name: Create success summary | |
| run: | | |
| echo "## π Release Published Successfully!" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Version: ${{ steps.package-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "β **All tests passed on all platforms**" >> $GITHUB_STEP_SUMMARY | |
| echo "β **Documentation deployed**" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Links:" >> $GITHUB_STEP_SUMMARY | |
| echo "- π¦ [npm Package](https://www.npmjs.com/package/@codedir/mimir-code)" >> $GITHUB_STEP_SUMMARY | |
| echo "- π·οΈ [GitHub Release](https://github.com/codedir-labs/mimir-code/releases/tag/${{ steps.package-version.outputs.tag }})" >> $GITHUB_STEP_SUMMARY | |
| echo "- π [Documentation](https://codedir-labs.github.io/mimir-code/)" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Installation:" >> $GITHUB_STEP_SUMMARY | |
| echo '```bash' >> $GITHUB_STEP_SUMMARY | |
| echo "# npm" >> $GITHUB_STEP_SUMMARY | |
| echo "npm install -g @codedir/mimir-code" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "# Unix (curl/bash)" >> $GITHUB_STEP_SUMMARY | |
| echo "curl -fsSL https://raw.githubusercontent.com/codedir-labs/mimir-code/main/scripts/install.sh | bash" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "# Windows (PowerShell)" >> $GITHUB_STEP_SUMMARY | |
| echo "iwr -useb https://raw.githubusercontent.com/codedir-labs/mimir-code/main/scripts/install.ps1 | iex" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY |