deps-dev(deps-dev): bump tsx from 4.19.4 to 4.20.6 #185
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: CI/CD Pipeline | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. | |
| concurrency: | |
| group: "ci-cd-${{ github.ref }}" | |
| cancel-in-progress: false | |
| jobs: | |
| # Quality Gates - All quality checks must pass before anything else | |
| quality: | |
| runs-on: ${{ matrix.os }} | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| issues: write | |
| strategy: | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| node-version: [20.x, 22.x] # Removed 18.x due to semantic-release compatibility | |
| include: | |
| # Test case-sensitive filesystem behavior on macOS (default) and Linux | |
| - os: ubuntu-latest | |
| node-version: 20.x | |
| filesystem-case: sensitive | |
| - os: macos-latest | |
| node-version: 20.x | |
| filesystem-case: insensitive | |
| # Test Windows path separators and drive letters | |
| - os: windows-latest | |
| node-version: 20.x | |
| filesystem-case: insensitive | |
| path-separator: backslash | |
| fail-fast: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| - name: Configure OS-specific environment | |
| run: | | |
| echo "OS: ${{ matrix.os }}" | |
| echo "Node: ${{ matrix.node-version }}" | |
| echo "Filesystem case: ${{ matrix.filesystem-case }}" | |
| echo "Path separator: ${{ matrix.path-separator }}" | |
| # Set environment variables for cross-platform testing | |
| echo "MARKMV_TEST_OS=${{ matrix.os }}" >> $GITHUB_ENV | |
| echo "MARKMV_TEST_CASE_SENSITIVE=${{ matrix.filesystem-case == 'sensitive' }}" >> $GITHUB_ENV | |
| echo "MARKMV_TEST_PATH_SEP=${{ matrix.path-separator || 'slash' }}" >> $GITHUB_ENV | |
| shell: bash | |
| - name: Setup Node.js ${{ matrix.node-version }} | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: 'npm' | |
| - name: Cache TypeScript build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| dist/ | |
| tsconfig.tsbuildinfo | |
| key: ${{ runner.os }}-tsc-${{ matrix.node-version }}-${{ hashFiles('src/**/*.ts', 'tsconfig.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-tsc-${{ matrix.node-version }}- | |
| ${{ runner.os }}-tsc- | |
| - name: Cache test results | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| coverage/ | |
| .vitest/ | |
| key: ${{ runner.os }}-test-${{ matrix.node-version }}-${{ hashFiles('src/**/*.ts', 'src/**/*.test.ts', 'vitest.config.ts') }} | |
| restore-keys: | | |
| ${{ runner.os }}-test-${{ matrix.node-version }}- | |
| ${{ runner.os }}-test- | |
| - name: Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| # Auto-fix linting issues (only on push to main, only on Node.js 22.x and Ubuntu to avoid race conditions) | |
| - name: Check for fixable linting issues | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.node-version == '22.x' && matrix.os == 'ubuntu-latest' | |
| id: check-fixes | |
| run: | | |
| git status --porcelain > before.txt | |
| npm run lint:fix || true | |
| npm run format || true | |
| git status --porcelain > after.txt | |
| if ! diff before.txt after.txt >/dev/null; then | |
| echo "fixes-available=true" >> $GITHUB_OUTPUT | |
| git checkout -- . | |
| else | |
| echo "fixes-available=false" >> $GITHUB_OUTPUT | |
| fi | |
| rm -f before.txt after.txt | |
| - name: Auto-fix linting issues | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.node-version == '22.x' && matrix.os == 'ubuntu-latest' && steps.check-fixes.outputs.fixes-available == 'true' | |
| run: | | |
| npm run lint:fix | |
| npm run format | |
| - name: Commit auto-fixes | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.node-version == '22.x' && matrix.os == 'ubuntu-latest' && steps.check-fixes.outputs.fixes-available == 'true' | |
| run: | | |
| git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git config --local user.name "github-actions[bot]" | |
| git add . | |
| if ! git diff --cached --quiet; then | |
| git commit -m "style: auto-fix linting issues" | |
| git push | |
| fi | |
| # Generate required files before quality checks | |
| - name: Generate schemas (required for TypeScript compilation) | |
| run: npm run generate:schemas | |
| - name: Format generated files | |
| run: npm run format | |
| # Quality checks (must pass for all further steps) | |
| - name: Run lint (fast fail) | |
| run: npm run lint | |
| - name: Check formatting (fast fail) | |
| run: npm run format:check | |
| - name: Run type check (fast fail) | |
| run: npm run typecheck | |
| - name: Run security audit | |
| run: npm audit --audit-level=high | |
| continue-on-error: true | |
| - name: Build | |
| run: npm run build | |
| - name: Create filesystem test environment | |
| run: | | |
| # Create test directories for cross-platform filesystem testing | |
| mkdir -p test-filesystem/case-test | |
| mkdir -p test-filesystem/path-test | |
| mkdir -p test-filesystem/symlink-test | |
| # Test case sensitivity (if supported) | |
| cd test-filesystem/case-test | |
| echo "lowercase content" > testfile.txt | |
| echo "uppercase content" > TESTFILE.TXT | |
| # Count files to detect case sensitivity | |
| FILE_COUNT=$(ls testfile.txt TESTFILE.TXT 2>/dev/null | wc -l || echo "0") | |
| echo "FILESYSTEM_CASE_TEST_COUNT=$FILE_COUNT" >> $GITHUB_ENV | |
| if [ "$FILE_COUNT" -eq "2" ]; then | |
| echo "✅ Case-sensitive filesystem detected" | |
| echo "FILESYSTEM_IS_CASE_SENSITIVE=true" >> $GITHUB_ENV | |
| else | |
| echo "✅ Case-insensitive filesystem detected" | |
| echo "FILESYSTEM_IS_CASE_SENSITIVE=false" >> $GITHUB_ENV | |
| fi | |
| cd ../.. | |
| shell: bash | |
| - name: Test filesystem behaviors | |
| run: | | |
| echo "🧪 Testing filesystem behaviors..." | |
| echo "Expected case sensitivity: ${{ matrix.filesystem-case }}" | |
| echo "Detected case sensitivity: $FILESYSTEM_IS_CASE_SENSITIVE" | |
| echo "File count in case test: $FILESYSTEM_CASE_TEST_COUNT" | |
| # Test path separators | |
| if [ "${{ runner.os }}" = "Windows" ]; then | |
| echo "Testing Windows path separators..." | |
| # Test with both forward and back slashes | |
| echo "test content" > "test-filesystem\\path-test\\backslash.txt" || echo "Backslash path failed" | |
| echo "test content" > "test-filesystem/path-test/forward.txt" || echo "Forward slash path failed" | |
| else | |
| echo "Testing Unix-like path separators..." | |
| echo "test content" > "test-filesystem/path-test/unix.txt" | |
| fi | |
| # Test symbolic links (if supported) | |
| cd test-filesystem/symlink-test | |
| echo "original content" > original.txt | |
| ln -s original.txt symlink.txt 2>/dev/null || echo "Symlinks not supported on this filesystem" | |
| if [ -L symlink.txt ]; then | |
| echo "✅ Symbolic links supported" | |
| echo "FILESYSTEM_SUPPORTS_SYMLINKS=true" >> $GITHUB_ENV | |
| else | |
| echo "❌ Symbolic links not supported" | |
| echo "FILESYSTEM_SUPPORTS_SYMLINKS=false" >> $GITHUB_ENV | |
| fi | |
| cd ../.. | |
| shell: bash | |
| - name: Run tests with OS-specific environment | |
| env: | |
| MARKMV_TEST_FILESYSTEM_CASE_SENSITIVE: ${{ env.FILESYSTEM_IS_CASE_SENSITIVE }} | |
| MARKMV_TEST_SUPPORTS_SYMLINKS: ${{ env.FILESYSTEM_SUPPORTS_SYMLINKS }} | |
| run: npm run test:run | |
| - name: Report filesystem test results | |
| run: | | |
| echo "## 🖥️ Filesystem Test Results - ${{ matrix.os }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Node Version:** ${{ matrix.node-version }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Case Sensitivity:** $FILESYSTEM_IS_CASE_SENSITIVE" >> $GITHUB_STEP_SUMMARY | |
| echo "**Symlink Support:** $FILESYSTEM_SUPPORTS_SYMLINKS" >> $GITHUB_STEP_SUMMARY | |
| echo "**Path Separator:** ${{ matrix.path-separator || 'forward-slash' }}" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| # Coverage generation (only on Node 20.x and Ubuntu to avoid duplication) | |
| - name: Generate test coverage | |
| if: matrix.node-version == '20.x' && matrix.os == 'ubuntu-latest' | |
| run: | | |
| npm run test:coverage | tee coverage-output.txt | |
| # Extract overall coverage percentage | |
| COVERAGE=$(grep "All files" coverage-output.txt | awk '{print $4}' | head -1) | |
| echo "TEST_COVERAGE=$COVERAGE" >> $GITHUB_ENV | |
| echo "📊 Test coverage: $COVERAGE%" >> $GITHUB_STEP_SUMMARY | |
| - name: Generate documentation coverage | |
| if: matrix.node-version == '20.x' && matrix.os == 'ubuntu-latest' | |
| run: | | |
| # Generate regular report for summary | |
| npm run docs:coverage | |
| # Generate JSON report for programmatic access (suppress all output to avoid warnings in JSON) | |
| DOCS_COVERAGE=$(OUTPUT_JSON=true node scripts/check-docs-coverage.js 2>/dev/null | jq -r '.overallCoverage') | |
| # If jq failed, try to extract directly from the script output | |
| if [ -z "$DOCS_COVERAGE" ] || [ "$DOCS_COVERAGE" = "null" ]; then | |
| DOCS_COVERAGE=$(OUTPUT_JSON=true node scripts/check-docs-coverage.js 2>/dev/null | grep -o '"overallCoverage":[0-9.]*' | cut -d':' -f2) | |
| fi | |
| echo "DOCS_COVERAGE=$DOCS_COVERAGE" >> $GITHUB_ENV | |
| echo "📚 Documentation coverage: $DOCS_COVERAGE%" >> $GITHUB_STEP_SUMMARY | |
| # Save JSON for artifacts (optional) | |
| OUTPUT_JSON=true node scripts/check-docs-coverage.js 2>/dev/null > docs-coverage.json || echo '{"overallCoverage": 0}' > docs-coverage.json | |
| - name: Upload coverage artifacts | |
| if: matrix.node-version == '20.x' && matrix.os == 'ubuntu-latest' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-reports | |
| path: | | |
| coverage/ | |
| coverage-output.txt | |
| docs-coverage.json | |
| retention-days: 30 | |
| # Release - Only after quality checks pass, includes README generation and badge updates | |
| release: | |
| needs: quality | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| permissions: | |
| contents: write | |
| issues: write | |
| pull-requests: write | |
| id-token: write | |
| attestations: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.SEMANTIC_RELEASE_TOKEN || secrets.GITHUB_TOKEN }} | |
| # Get the latest commit (including badge updates) | |
| ref: main | |
| # Note: Using GITHUB_TOKEN instead of GitHub App token for GitHub Packages compatibility | |
| # GitHub Packages npm registry doesn't support GitHub App installation tokens | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| cache: 'npm' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| - name: Download coverage artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: coverage-reports | |
| continue-on-error: true | |
| - name: Upload coverage to Coveralls | |
| if: hashFiles('coverage/lcov.info') != '' | |
| uses: coverallsapp/github-action@v2 | |
| with: | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| path-to-lcov: ./coverage/lcov.info | |
| continue-on-error: true | |
| - name: Build | |
| run: npm run build | |
| - name: Verify build output | |
| run: | | |
| ls -la dist/ | |
| node dist/cli.js --version || echo "CLI not yet ready" | |
| - name: Generate SBOM for NPM attestations | |
| uses: anchore/sbom-action@v0.17.8 | |
| with: | |
| path: ./ | |
| format: spdx-json | |
| output-file: sbom.spdx.json | |
| upload-artifact: true | |
| upload-release-assets: false | |
| # Temporarily disabled due to Sigstore timeout issues | |
| # - name: Generate build attestations for NPM | |
| # uses: actions/attest-build-provenance@v1 | |
| # id: attest-build | |
| # with: | |
| # subject-path: 'dist/**/*' | |
| # push-to-registry: false | |
| # - name: Generate SBOM attestations for NPM | |
| # uses: actions/attest-sbom@v1 | |
| # id: attest-sbom | |
| # with: | |
| # subject-path: 'dist/**/*' | |
| # sbom-path: 'sbom.spdx.json' | |
| # push-to-registry: false | |
| # Pre-release: Generate README and update badges BEFORE semantic-release | |
| - name: Generate updated README for release | |
| run: | | |
| echo "🔄 Generating README from TypeScript documentation..." | |
| npm run docs:readme-generate | |
| - name: Extract coverage data for badges | |
| id: coverage | |
| run: | | |
| # Test coverage | |
| if [ -f "coverage-output.txt" ]; then | |
| TEST_COV=$(grep "All files" coverage-output.txt | awk '{print $4}' | head -1) | |
| else | |
| TEST_COV="unknown" | |
| fi | |
| # Documentation coverage | |
| if [ -f "docs-coverage.json" ]; then | |
| DOCS_COV=$(jq -r '.overallCoverage' docs-coverage.json) | |
| else | |
| DOCS_COV="unknown" | |
| fi | |
| echo "test-coverage=$TEST_COV" >> $GITHUB_OUTPUT | |
| echo "docs-coverage=$DOCS_COV" >> $GITHUB_OUTPUT | |
| echo "📊 Test Coverage: $TEST_COV% | Documentation Coverage: $DOCS_COV%" | |
| - name: Determine badge colors | |
| id: colors | |
| run: | | |
| # Test coverage color | |
| TEST_COV="${{ steps.coverage.outputs.test-coverage }}" | |
| if [ "$TEST_COV" = "unknown" ]; then | |
| TEST_COLOR="lightgrey" | |
| else | |
| TEST_NUM=$(echo "$TEST_COV" | sed 's/%//' | cut -d'.' -f1) | |
| if [ "$TEST_NUM" -ge 90 ]; then | |
| TEST_COLOR="brightgreen" | |
| elif [ "$TEST_NUM" -ge 80 ]; then | |
| TEST_COLOR="green" | |
| elif [ "$TEST_NUM" -ge 70 ]; then | |
| TEST_COLOR="yellow" | |
| elif [ "$TEST_NUM" -ge 60 ]; then | |
| TEST_COLOR="orange" | |
| else | |
| TEST_COLOR="red" | |
| fi | |
| fi | |
| # Documentation coverage color | |
| DOCS_COV="${{ steps.coverage.outputs.docs-coverage }}" | |
| if [ "$DOCS_COV" = "unknown" ]; then | |
| DOCS_COLOR="lightgrey" | |
| else | |
| DOCS_NUM=$(echo "$DOCS_COV" | sed 's/%//' | cut -d'.' -f1) | |
| if [ "$DOCS_NUM" -ge 95 ]; then | |
| DOCS_COLOR="brightgreen" | |
| elif [ "$DOCS_NUM" -ge 90 ]; then | |
| DOCS_COLOR="green" | |
| elif [ "$DOCS_NUM" -ge 80 ]; then | |
| DOCS_COLOR="yellow" | |
| elif [ "$DOCS_NUM" -ge 70 ]; then | |
| DOCS_COLOR="orange" | |
| else | |
| DOCS_COLOR="red" | |
| fi | |
| fi | |
| echo "test-color=$TEST_COLOR" >> $GITHUB_OUTPUT | |
| echo "docs-color=$DOCS_COLOR" >> $GITHUB_OUTPUT | |
| - name: Update README badges before release | |
| run: | | |
| echo "🎨 Updating coverage badges in README..." | |
| # Use current commit hash as base for badges (will be the commit before release) | |
| CURRENT_HASH=$(git rev-parse HEAD) | |
| TEST_COV="${{ steps.coverage.outputs.test-coverage }}" | |
| DOCS_COV="${{ steps.coverage.outputs.docs-coverage }}" | |
| TEST_COLOR="${{ steps.colors.outputs.test-color }}" | |
| DOCS_COLOR="${{ steps.colors.outputs.docs-color }}" | |
| # URL encode percentage signs | |
| TEST_COV_ENCODED=$(echo "$TEST_COV" | sed 's/%/%25/g') | |
| DOCS_COV_ENCODED=$(echo "$DOCS_COV" | sed 's/%/%25/g') | |
| # Create new badge URLs with current commit hash | |
| TEST_BADGE="[](https://github.com/ExaDev/markmv/commit/${CURRENT_HASH})" | |
| DOCS_BADGE="[](https://github.com/ExaDev/markmv/commit/${CURRENT_HASH})" | |
| # Update README.md | |
| awk -v test_badge="$TEST_BADGE" -v docs_badge="$DOCS_BADGE" ' | |
| /\[\!\[Test Coverage\]/ { print test_badge; next } | |
| /\[\!\[Documentation Coverage\]/ { print docs_badge; next } | |
| { print } | |
| ' README.md > README.md.tmp && mv README.md.tmp README.md | |
| echo "✅ README badges updated with current coverage data (commit: ${CURRENT_HASH})" | |
| - name: Stage README and badge updates for release | |
| run: | | |
| if ! git diff --quiet; then | |
| echo "📝 Staging README and badge updates for inclusion in release commit..." | |
| git add README.md | |
| echo "✅ Changes staged and ready for semantic-release" | |
| else | |
| echo "ℹ️ No README changes to stage" | |
| fi | |
| - name: Prepare GitHub Packages publishing | |
| run: | | |
| echo "📦 Preparing package configuration for GitHub Packages..." | |
| # Create dist-github directory and copy ALL build artifacts | |
| mkdir -p dist-github | |
| cp -r dist/* dist-github/ 2>/dev/null || echo "Warning: No dist files found" | |
| # Verify binary files exist and are executable | |
| if [ -f "dist-github/cli.js" ]; then | |
| chmod +x dist-github/cli.js | |
| echo "✅ CLI binary found and made executable" | |
| else | |
| echo "❌ CLI binary not found in dist-github/" | |
| ls -la dist-github/ || echo "dist-github directory is empty" | |
| ls -la dist/ || echo "dist directory not found" | |
| exit 1 | |
| fi | |
| # Create a scoped package.json for GitHub Packages (fix paths and remove prepublishOnly script) | |
| # NOTE: Using user-scoped package @mearman/markmv to bypass organization permission issues | |
| jq '.name = "@mearman/markmv" | .publishConfig.registry = "https://npm.pkg.github.com" | del(.scripts.prepublishOnly) | .bin.markmv = "./cli.js" | .main = "./index.js" | .types = "./index.d.ts"' package.json > dist-github/package.json | |
| # Copy other required files to dist-github | |
| cp README.md CHANGELOG.md LICENSE dist-github/ 2>/dev/null || true | |
| # Show final structure | |
| echo "📁 Final dist-github structure:" | |
| ls -la dist-github/ | |
| echo "✅ GitHub Packages configuration prepared" | |
| - name: Release (includes README and badge updates) | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.SEMANTIC_RELEASE_TOKEN || secrets.GITHUB_TOKEN }} | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| # Environment variables for npm-multiple plugin | |
| NPMJS_NPM_CONFIG_REGISTRY: https://registry.npmjs.org/ | |
| NPMJS_NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| GITHUB_NPM_CONFIG_REGISTRY: https://npm.pkg.github.com | |
| GITHUB_NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| echo "🚀 Starting semantic-release with staged README and badge updates..." | |
| # Set up .npmrc for both registries | |
| cat > .npmrc << EOF | |
| registry=https://registry.npmjs.org/ | |
| //registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }} | |
| //npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }} | |
| @mearman:registry=https://npm.pkg.github.com | |
| EOF | |
| # Copy .npmrc to dist-github for GitHub Packages authentication | |
| cp .npmrc dist-github/ | |
| npm run release | |
| echo "✅ Release completed - version tagged and prepared for publishing" | |
| # Temporarily disabled - attestation verification step | |
| # - name: Verify attestations are available for NPM | |
| # run: | | |
| # echo "🔍 Verifying attestations are ready for NPM publishing..." | |
| # | |
| # # Check if attestations were generated | |
| # if [ -f "${{ steps.attest-build.outputs.bundle-path }}" ]; then | |
| # echo "✅ Build attestation available: ${{ steps.attest-build.outputs.bundle-path }}" | |
| # ls -la "${{ steps.attest-build.outputs.bundle-path }}" | |
| # else | |
| # echo "⚠️ No build attestation bundle found" | |
| # fi | |
| # | |
| # if [ -f "${{ steps.attest-sbom.outputs.bundle-path }}" ]; then | |
| # echo "✅ SBOM attestation available: ${{ steps.attest-sbom.outputs.bundle-path }}" | |
| # ls -la "${{ steps.attest-sbom.outputs.bundle-path }}" | |
| # else | |
| # echo "⚠️ No SBOM attestation bundle found" | |
| # fi | |
| # | |
| # # Verify SBOM file is available | |
| # if [ -f "sbom.spdx.json" ]; then | |
| # echo "✅ SBOM file available: sbom.spdx.json" | |
| # ls -la sbom.spdx.json | |
| # else | |
| # echo "⚠️ SBOM file not found" | |
| # fi | |
| # | |
| # echo "📦 NPM provenance is enabled in package.json publishConfig" | |
| # echo "🔐 Attestations will be automatically linked to published package" | |
| # Separate NPM Publishing Step | |
| - name: Publish to NPM Registry | |
| continue-on-error: true | |
| run: | | |
| echo "📦 Publishing to NPM registry..." | |
| # Check if we can publish directly from the project root | |
| # since semantic-release has already prepared the package | |
| if [ -f "package.json" ]; then | |
| echo "✅ Found package.json, attempting direct publish" | |
| # Publish with provenance from current directory | |
| npm publish --provenance --access public | |
| if [ $? -eq 0 ]; then | |
| echo "✅ Successfully published to NPM" | |
| else | |
| echo "❌ NPM publishing failed, checking for tarball alternative" | |
| # Fallback: try to find and extract the tarball | |
| TARBALL=$(ls dist/markmv-*.tgz 2>/dev/null | head -1) | |
| if [ -n "$TARBALL" ] && [ -f "$TARBALL" ]; then | |
| echo "📦 Found tarball: $TARBALL" | |
| echo "📁 Extracting tarball for direct publish..." | |
| # Extract to a temporary directory and publish from there | |
| mkdir -p /tmp/npm-publish | |
| tar -xzf "$TARBALL" -C /tmp/npm-publish --strip-components=1 | |
| cd /tmp/npm-publish | |
| echo "📋 Publishing from extracted directory..." | |
| npm publish --provenance --access public | |
| if [ $? -eq 0 ]; then | |
| echo "✅ Successfully published to NPM from extracted tarball" | |
| else | |
| echo "❌ NPM publishing failed even from extracted tarball" | |
| fi | |
| else | |
| echo "❌ No tarball found for fallback publishing" | |
| echo "📁 Contents of dist directory:" | |
| ls -la dist/ || echo "No dist directory" | |
| fi | |
| fi | |
| else | |
| echo "❌ No package.json found for publishing" | |
| fi | |
| # Separate GitHub Packages Publishing Step | |
| - name: Publish to GitHub Packages | |
| continue-on-error: true | |
| run: | | |
| echo "📦 Publishing to GitHub Packages as @mearman/markmv..." | |
| # Check if dist-github directory exists | |
| if [ -d "dist-github" ]; then | |
| echo "✅ Found dist-github directory" | |
| ls -la dist-github/ | |
| # Verify package.json is configured correctly | |
| echo "📋 Package configuration:" | |
| cat dist-github/package.json | jq '.name, .publishConfig' | |
| # Publish to GitHub Packages | |
| cd dist-github && npm publish --registry https://npm.pkg.github.com --access public | |
| if [ $? -eq 0 ]; then | |
| echo "✅ Successfully published to GitHub Packages" | |
| else | |
| echo "❌ GitHub Packages publishing failed" | |
| fi | |
| else | |
| echo "❌ No dist-github directory found" | |
| fi | |
| # Summary of Publishing Results | |
| - name: Publishing Summary | |
| run: | | |
| echo "📊 Publishing Summary:" | |
| echo "====================" | |
| # Check NPM | |
| LATEST_NPM=$(npm view markmv version 2>/dev/null || echo "unknown") | |
| echo "📦 NPM Registry: $LATEST_NPM" | |
| # Check GitHub Packages | |
| LATEST_GH=$(npm view @mearman/markmv version --registry https://npm.pkg.github.com 2>/dev/null || echo "unknown") | |
| echo "📦 GitHub Packages: $LATEST_GH" | |
| echo "====================" | |
| echo "🔍 For installation instructions, see the release notes" | |
| # Documentation Deployment - Only after successful release with updated version | |
| documentation: | |
| needs: [quality, release] | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| permissions: | |
| contents: read | |
| pages: write | |
| id-token: write | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| # Get the latest commit (including version updates from release) | |
| ref: main | |
| fetch-depth: 1 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| cache: 'npm' | |
| - name: Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| - name: Build project | |
| run: npm run build | |
| - name: Show current project status | |
| run: | | |
| echo "## 📊 Documentation Build Status" >> $GITHUB_STEP_SUMMARY | |
| echo "**Current Version:** $(node -p "require('./package.json').version")" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Coverage Badges:**" >> $GITHUB_STEP_SUMMARY | |
| grep -E "(Test Coverage|Documentation Coverage)" README.md >> $GITHUB_STEP_SUMMARY || echo "No coverage badges found" >> $GITHUB_STEP_SUMMARY | |
| - name: Generate documentation | |
| run: npm run docs | |
| - name: Setup Pages | |
| id: pages | |
| uses: actions/configure-pages@v4 | |
| - name: Upload artifact | |
| uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: ./docs | |
| - name: Deploy to GitHub Pages | |
| id: deployment | |
| uses: actions/deploy-pages@v4 |