Skip to content

chore: adjust install and build release #29

chore: adjust install and build release

chore: adjust install and build release #29

Workflow file for this run

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