chore: debug verbose npm #43
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..." | |
| # Refresh PATH from environment | |
| $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| # 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 }} | |
| # Refresh PATH again | |
| $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| # 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 command (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Testing mimir uninstall..." | |
| mimir uninstall --yes --keep-config | |
| # Clear shell cache | |
| hash -r | |
| # Verify binary file is removed | |
| if [ ! -f "$HOME/.local/bin/mimir" ]; then | |
| echo "✅ Binary file removed from ~/.local/bin" | |
| else | |
| echo "❌ Binary file still exists" | |
| exit 1 | |
| fi | |
| # Verify binary directory is removed | |
| if [ ! -d "$HOME/.mimir/bin" ]; then | |
| echo "✅ Binary directory removed" | |
| else | |
| echo "❌ Binary directory still exists" | |
| exit 1 | |
| fi | |
| # Start new shell to verify command is truly gone | |
| if bash -c 'command -v mimir' &> /dev/null; then | |
| echo "❌ mimir command still available in new shell" | |
| exit 1 | |
| else | |
| echo "✅ mimir command not found in new shell" | |
| fi | |
| # Config should still exist (we chose to keep it) | |
| if [ -d "$HOME/.mimir" ]; then | |
| echo "✅ Config preserved when requested" | |
| else | |
| echo "❌ Config was removed unexpectedly" | |
| exit 1 | |
| fi | |
| - name: Test uninstall command (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing mimir uninstall..." | |
| # Refresh PATH from environment | |
| $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| # Save PATH before uninstall for comparison | |
| $pathBefore = [Environment]::GetEnvironmentVariable("Path", "User") | |
| $pathEntriesBefore = $pathBefore -split ';' | Where-Object { $_ } | |
| Write-Host "PATH entries before: $($pathEntriesBefore.Count)" | |
| mimir uninstall --yes --keep-config | |
| Write-Host "Waiting 5 seconds for deferred cleanup to complete..." | |
| Start-Sleep -Seconds 5 | |
| # Verify binary file is removed | |
| $localBinPath = "$env:USERPROFILE\.local\bin\mimir" | |
| if (-not (Test-Path $localBinPath) -and -not (Test-Path "$localBinPath.exe") -and -not (Test-Path "$localBinPath.cmd")) { | |
| Write-Host "✅ Binary file removed from .local/bin" | |
| } else { | |
| Write-Host "❌ Binary file still exists" | |
| if (Test-Path $localBinPath) { Write-Host " Found: $localBinPath" } | |
| if (Test-Path "$localBinPath.exe") { Write-Host " Found: $localBinPath.exe" } | |
| if (Test-Path "$localBinPath.cmd") { Write-Host " Found: $localBinPath.cmd" } | |
| exit 1 | |
| } | |
| # Verify binary directory is removed | |
| if (-not (Test-Path "$env:USERPROFILE\.mimir\bin")) { | |
| Write-Host "✅ Binary directory removed" | |
| } else { | |
| Write-Host "❌ Binary directory still exists" | |
| exit 1 | |
| } | |
| # Verify PATH was updated (mimir entries removed) | |
| $pathAfter = [Environment]::GetEnvironmentVariable("Path", "User") | |
| $pathEntriesAfter = $pathAfter -split ';' | Where-Object { $_ } | |
| Write-Host "PATH entries after: $($pathEntriesAfter.Count)" | |
| # Check that mimir-related entries were removed | |
| $mimirEntriesBefore = $pathEntriesBefore | Where-Object { $_ -like '*mimir*' } | |
| $mimirEntriesAfter = $pathEntriesAfter | Where-Object { $_ -like '*mimir*' } | |
| if ($mimirEntriesBefore.Count -gt 0 -and $mimirEntriesAfter.Count -eq 0) { | |
| Write-Host "✅ Removed $($mimirEntriesBefore.Count) mimir PATH entry/entries" | |
| } elseif ($mimirEntriesBefore.Count -eq 0) { | |
| Write-Host "✅ No mimir entries were in PATH (expected for this test)" | |
| } else { | |
| Write-Host "❌ mimir entries still in PATH" | |
| Write-Host " Before: $($mimirEntriesBefore.Count)" | |
| Write-Host " After: $($mimirEntriesAfter.Count)" | |
| exit 1 | |
| } | |
| # Verify non-mimir PATH entries were preserved | |
| $nonMimirBefore = $pathEntriesBefore | Where-Object { $_ -notlike '*mimir*' } | |
| $nonMimirAfter = $pathEntriesAfter | Where-Object { $_ -notlike '*mimir*' } | |
| if ($nonMimirBefore.Count -eq $nonMimirAfter.Count) { | |
| Write-Host "✅ Non-mimir PATH entries preserved ($($nonMimirBefore.Count) entries)" | |
| } else { | |
| Write-Host "⚠️ WARNING: Non-mimir PATH entries changed" | |
| Write-Host " Before: $($nonMimirBefore.Count)" | |
| Write-Host " After: $($nonMimirAfter.Count)" | |
| } | |
| # Verify command is not found in new PowerShell session | |
| $mimirExists = pwsh -NoProfile -Command "Get-Command mimir -ErrorAction SilentlyContinue" | |
| if (-not $mimirExists) { | |
| Write-Host "✅ mimir command not found in new PowerShell session" | |
| $global:LASTEXITCODE = 0 | |
| } else { | |
| Write-Host "❌ mimir command still available in new PowerShell session" | |
| exit 1 | |
| } | |
| # Config should still exist (we chose to keep it) | |
| if (Test-Path "$env:USERPROFILE\.mimir") { | |
| Write-Host "✅ Config preserved when requested" | |
| } else { | |
| Write-Host "❌ Config was removed unexpectedly" | |
| exit 1 | |
| } | |
| # Ensure script exits with 0 (all tests passed) | |
| exit 0 | |
| - 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 registry on all platforms | |
| # Runs only after npm package is successfully published | |
| test-npm-installation: | |
| name: Test npm Installation - ${{ matrix.name }} | |
| needs: [publish-npm] # Only run after npm package is published | |
| 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 | |
| - os: macos-latest | |
| name: macOS | |
| shell: bash | |
| config_path: ~/.mimir/config.yml | |
| - os: windows-latest | |
| name: Windows | |
| shell: pwsh | |
| config_path: $env:USERPROFILE\.mimir\config.yml | |
| 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: Test npm global installation (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Testing npm global installation..." | |
| # Install from npm registry | |
| npm install -g @codedir/mimir-code | |
| # Verify installation | |
| if command -v mimir &> /dev/null; then | |
| echo "✅ mimir command available" | |
| else | |
| echo "❌ mimir command not found" | |
| exit 1 | |
| fi | |
| # Test that mimir can execute | |
| mimir --version || { | |
| echo "❌ mimir --version failed" | |
| exit 1 | |
| } | |
| echo "✅ mimir executes successfully" | |
| # Initialize config directory | |
| mimir init --no-interactive --quiet || { | |
| echo "❌ mimir init failed" | |
| exit 1 | |
| } | |
| # Verify config directory created | |
| if [ -d "$HOME/.mimir" ]; then | |
| echo "✅ Config directory created" | |
| else | |
| echo "❌ Config directory not found" | |
| exit 1 | |
| fi | |
| - name: Test npm global installation (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing npm global installation..." | |
| # Install from npm registry | |
| npm install -g @codedir/mimir-code | |
| # Get npm global bin directory and add to PATH | |
| $npmBin = npm bin -g | |
| $env:Path = "$npmBin;" + [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| # Verify installation | |
| $mimirCmd = Get-Command mimir -ErrorAction SilentlyContinue | |
| if ($mimirCmd) { | |
| Write-Host "✅ mimir command available" | |
| Write-Host " Path: $($mimirCmd.Source)" | |
| } else { | |
| Write-Host "❌ mimir command not found" | |
| Write-Host "Debugging info:" | |
| Write-Host " npm prefix: $(npm prefix -g)" | |
| Write-Host " npm bin: $npmBin" | |
| Write-Host " Current PATH: $env:Path" | |
| exit 1 | |
| } | |
| # Test that mimir can execute | |
| mimir --version | |
| if ($LASTEXITCODE -ne 0) { | |
| Write-Host "❌ mimir --version failed" | |
| exit 1 | |
| } | |
| Write-Host "✅ mimir executes successfully" | |
| # Initialize config directory | |
| mimir init --no-interactive --quiet | |
| if ($LASTEXITCODE -ne 0) { | |
| Write-Host "❌ mimir init failed" | |
| exit 1 | |
| } | |
| # Verify config directory created | |
| if (Test-Path "$env:USERPROFILE\.mimir") { | |
| Write-Host "✅ Config directory created" | |
| } else { | |
| Write-Host "❌ Config directory not found" | |
| exit 1 | |
| } | |
| - 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 | |
| # Upgrade via npm (will reinstall latest version) | |
| npm update -g @codedir/mimir-code | |
| # 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 | |
| # Verify command still works | |
| mimir --version | |
| - name: Test upgrade scenario (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing npm upgrade scenario..." | |
| # Refresh PATH with npm bin | |
| $npmBin = npm bin -g | |
| $env:Path = "$npmBin;" + [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| # 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" | |
| # Upgrade via npm | |
| npm update -g @codedir/mimir-code | |
| # Refresh PATH again | |
| $npmBin = npm bin -g | |
| $env:Path = "$npmBin;" + [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| # 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 | |
| } | |
| # Verify command still works | |
| mimir --version | |
| - name: Test uninstall (Unix) | |
| if: matrix.shell == 'bash' | |
| run: | | |
| echo "Testing mimir uninstall command..." | |
| # First test mimir uninstall (should detect npm and provide instructions) | |
| # Use --yes and --keep-config flags for headless mode | |
| mimir uninstall --yes --keep-config | |
| # mimir should still be available (npm install requires npm uninstall) | |
| if command -v mimir &> /dev/null; then | |
| echo "✅ mimir still available (npm installation detected)" | |
| else | |
| echo "❌ mimir was removed unexpectedly" | |
| exit 1 | |
| fi | |
| echo "Testing npm uninstall..." | |
| # Now uninstall via npm | |
| npm uninstall -g @codedir/mimir-code | |
| # Verify command is removed | |
| if command -v mimir &> /dev/null; then | |
| echo "❌ mimir command still available after npm uninstall" | |
| exit 1 | |
| else | |
| echo "✅ mimir command removed" | |
| fi | |
| # Config should still exist (npm doesn't touch user data) | |
| if [ -d "$HOME/.mimir" ]; then | |
| echo "✅ Config directory preserved (as expected with npm uninstall)" | |
| else | |
| echo "⚠️ Config directory was removed (unexpected)" | |
| fi | |
| - name: Test uninstall (Windows) | |
| if: matrix.shell == 'pwsh' | |
| run: | | |
| Write-Host "Testing mimir uninstall command..." | |
| # Get npm global bin directory and add to PATH | |
| $npmBin = npm bin -g | |
| $env:Path = "$npmBin;" + [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") | |
| # Test mimir uninstall (should detect npm and not remove package) | |
| mimir uninstall --yes --keep-config | |
| # mimir should still be available (npm install requires npm uninstall) | |
| $mimirCmd = Get-Command mimir -ErrorAction SilentlyContinue | |
| if ($mimirCmd) { | |
| Write-Host "✅ mimir still available (npm installation detected)" | |
| } else { | |
| Write-Host "❌ mimir was removed unexpectedly" | |
| exit 1 | |
| } | |
| Write-Host "Testing npm uninstall..." | |
| # Now uninstall via npm | |
| npm uninstall -g @codedir/mimir-code | |
| # Verify command is removed | |
| $mimirCmd = Get-Command mimir -ErrorAction SilentlyContinue | |
| if ($mimirCmd) { | |
| Write-Host "❌ mimir command still available after npm uninstall" | |
| exit 1 | |
| } else { | |
| Write-Host "✅ mimir command removed" | |
| } | |
| # Config should still exist (npm doesn't touch user data) | |
| if (Test-Path "$env:USERPROFILE\.mimir") { | |
| Write-Host "✅ Config directory preserved (as expected with npm uninstall)" | |
| } else { | |
| Write-Host "⚠️ Config directory was removed (unexpected)" | |
| } | |
| # Ensure script exits with 0 (all tests passed) | |
| exit 0 | |
| - name: Create test summary | |
| if: success() | |
| run: | | |
| echo "✅ All npm tests passed on ${{ matrix.name }}" >> $GITHUB_STEP_SUMMARY | |
| echo " - npm global installation test passed" >> $GITHUB_STEP_SUMMARY | |
| echo " - npm upgrade test passed" >> $GITHUB_STEP_SUMMARY | |
| echo " - npm 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 |