fix: replace heredoc with printf in workflow files to fix YAML parsing #3
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: Release Test (Dry Run) | |
| on: | |
| # Trigger on test tags (e.g., test-v1.0.0, test-v1.2.3) | |
| push: | |
| tags: | |
| - 'test-v*.*.*' | |
| # Allow manual workflow dispatch for testing | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version to test (e.g., 1.0.0)' | |
| required: true | |
| type: string | |
| # Security: Minimal permissions (read-only for testing) | |
| permissions: | |
| contents: read # Only read (no publishing) | |
| jobs: | |
| test-release: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Use Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20.x' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Extract version from tag | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then | |
| VERSION="${{ github.event.inputs.version }}" | |
| else | |
| # Extract version from test tag (remove 'test-v' prefix) | |
| VERSION="${GITHUB_REF#refs/tags/test-v}" | |
| fi | |
| echo "version=$VERSION" >> $GITHUB_OUTPUT | |
| echo "tag=test-v$VERSION" >> $GITHUB_OUTPUT | |
| echo "📦 Test Version: $VERSION" | |
| # Security: Verify no package installations in workflow files | |
| - name: Security Check - No Package Installations | |
| run: | | |
| echo "🔍 Scanning workflow files for security..." | |
| # Check for actual install commands, excluding: | |
| # - Comment lines (containing # before the pattern) | |
| # - Documentation strings (in echo/heredoc) | |
| # - The grep command itself | |
| # - Lines that are clearly documentation | |
| if grep -rE "(npm install|npm ci|yarn install|pnpm install|bun install|pip install|pip3 install)" .github/workflows/ 2>/dev/null | \ | |
| grep -vE "#.*install|echo.*install|grep.*install|ERROR:|documentation|release notes|npm install -g|No.*install"; then | |
| echo "❌ ERROR: Package installation detected in workflow files!" | |
| exit 1 | |
| fi | |
| echo "✅ No package installations found in workflows" | |
| # Security: Verify package.json has zero dependencies | |
| - name: Security Check - Zero Dependencies | |
| run: | | |
| echo "🔍 Verifying package.json has zero dependencies..." | |
| if node -e "const pkg = require('./package.json'); if (pkg.dependencies || pkg.devDependencies) { console.error('ERROR: Dependencies found!'); process.exit(1); } else { console.log('✅ Zero dependencies confirmed'); }"; then | |
| echo "✅ Package has zero dependencies" | |
| else | |
| echo "❌ ERROR: Dependencies detected" | |
| exit 1 | |
| fi | |
| # Security: Verify no node_modules directory exists | |
| - name: Security Check - No node_modules | |
| run: | | |
| if [ -d "node_modules" ]; then | |
| echo "❌ ERROR: node_modules directory found!" | |
| exit 1 | |
| fi | |
| echo "✅ No node_modules directory found" | |
| - name: Verify version matches package.json | |
| run: | | |
| PACKAGE_VERSION=$(node -p "require('./package.json').version") | |
| if [ "$PACKAGE_VERSION" != "${{ steps.version.outputs.version }}" ]; then | |
| echo "⚠️ WARNING: Version mismatch!" | |
| echo " Tag version: ${{ steps.version.outputs.version }}" | |
| echo " package.json version: $PACKAGE_VERSION" | |
| echo " (This is OK for testing - just a warning)" | |
| else | |
| echo "✅ Version matches package.json" | |
| fi | |
| # Security: Verify package.json integrity | |
| - name: Security Check - Package.json Integrity | |
| run: | | |
| echo "🔍 Verifying package.json integrity..." | |
| node -e " | |
| const pkg = require('./package.json'); | |
| const scripts = pkg.scripts || {}; | |
| const suspicious = Object.keys(scripts).filter(k => | |
| k.includes('install') || k.includes('post') || k.includes('pre') | |
| ); | |
| if (suspicious.length > 0) { | |
| console.error('❌ ERROR: Suspicious scripts found:', suspicious); | |
| process.exit(1); | |
| } | |
| console.log('✅ Package.json integrity check passed'); | |
| " | |
| - name: Run tests | |
| run: | | |
| echo "🧪 Running tests..." | |
| npm run test:smoke | |
| - name: Test npm publish dry run | |
| run: | | |
| echo "🔍 Testing npm publish dry run (no actual publish)..." | |
| # This simulates what would be published without actually publishing | |
| npm pack --dry-run 2>&1 | head -20 | |
| echo "" | |
| echo "✅ Dry run successful - package would be published with these files:" | |
| npm pack --dry-run 2>&1 | grep -E "^\s+" | head -10 | |
| - name: Generate release notes (test) | |
| run: | | |
| VERSION="${{ steps.version.outputs.version }}" | |
| TAG="${{ steps.version.outputs.tag }}" | |
| REPO="${{ github.repository }}" | |
| echo "📝 Generating release notes (test)..." | |
| if [ -f CHANGELOG.md ]; then | |
| CHANGELOG_SECTION=$(awk -v version="$VERSION" ' | |
| /^## \[/ { | |
| if (found) exit | |
| if ($0 ~ "## \\[" version "\\]") { | |
| found = 1 | |
| next | |
| } | |
| } | |
| found { print } | |
| ' CHANGELOG.md) | |
| if [ -z "$CHANGELOG_SECTION" ]; then | |
| CHANGELOG_SECTION=$(printf "## Changes\n\nSee [CHANGELOG.md](https://github.com/%s/blob/main/CHANGELOG.md) for details." "$REPO") | |
| fi | |
| else | |
| CHANGELOG_SECTION=$(printf "## Changes\n\nSee commit history for details.") | |
| fi | |
| { | |
| echo "# 🛡️ Sentinel Package Manager $VERSION (TEST)" | |
| echo "" | |
| echo "$CHANGELOG_SECTION" | |
| echo "" | |
| echo "## 📦 Installation" | |
| echo "" | |
| echo "\`\`\`bash" | |
| echo "npm install -g @dreamhorizonorg/sentinel@$VERSION" | |
| echo "\`\`\`" | |
| echo "" | |
| echo "## 🔗 Links" | |
| echo "" | |
| echo "- **npm**: https://www.npmjs.com/package/@dreamhorizonorg/sentinel/v/$VERSION" | |
| echo "- **GitHub**: https://github.com/$REPO/releases/tag/$TAG" | |
| } > release_notes_test.md | |
| echo "✅ Release notes generated:" | |
| cat release_notes_test.md | |
| - name: Test summary | |
| run: | | |
| echo "## ✅ Release Test Complete!" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Test Version**: ${{ steps.version.outputs.tag }}" >> $GITHUB_STEP_SUMMARY | |
| echo "**Status**: All checks passed - ready for real release" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**What was tested:**" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Security checks" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Version verification" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Tests execution" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ npm publish dry run" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Release notes generation" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "**Next step**: Use a real tag (v*.*.*) to trigger actual release" >> $GITHUB_STEP_SUMMARY | |