feat(website): add seo enhancements with sitemap and structured data #21
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: Preview Packages | |
| on: | |
| pull_request: | |
| types: [opened, edited, synchronize, reopened] | |
| concurrency: | |
| group: preview-packages-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| env: | |
| PREVIEW_COMMENT_MARKER: '<!-- PKG_PR_NEW_PREVIEW_COMMENT -->' | |
| jobs: | |
| preview: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| package: | |
| # When you add a new package, add a new line here | |
| - name: "@nicepkg/vsync" | |
| dir: "cli" | |
| display: "vsync (CLI)" | |
| # - name: "core" | |
| # dir: "core" | |
| # display: "vsync (core)" | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup Node.js and pnpm | |
| uses: ./.github/actions/setup-node-pnpm | |
| with: | |
| install-dependencies: 'true' | |
| setup-cache: 'true' | |
| - name: Build package | |
| run: pnpm --filter "${{ matrix.package.name }}" build | |
| - name: Publish preview to pkg.pr.new (capture output) | |
| id: publish | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| # Pin version for stability | |
| OUT="$(npx -y pkg-pr-new@0.0.62 publish "./${{ matrix.package.dir }}" 2>&1 | tee /dev/stderr)" | |
| # Use a random delimiter to avoid "EOF" collisions in GitHub output parsing | |
| DELIM="EOF_$(date +%s)_$RANDOM" | |
| { | |
| echo "output<<$DELIM" | |
| echo "$OUT" | |
| echo "$DELIM" | |
| } >> "$GITHUB_OUTPUT" | |
| - name: Upsert PR comment (no spam) | |
| uses: actions/github-script@v8 | |
| env: | |
| MARKER: ${{ env.PREVIEW_COMMENT_MARKER }} | |
| PKG_DIR: ${{ matrix.package.dir }} | |
| PKG_DISPLAY: ${{ matrix.package.display }} | |
| PUBLISH_OUTPUT: ${{ steps.publish.outputs.output }} | |
| with: | |
| script: | | |
| const marker = process.env.MARKER; | |
| const dir = process.env.PKG_DIR; | |
| const display = process.env.PKG_DISPLAY; | |
| const out = process.env.PUBLISH_OUTPUT || ''; | |
| const lines = out.split('\n').map(s => s.trim()).filter(Boolean); | |
| // Prefer explicit pkg.pr.new install lines | |
| const installLine = | |
| lines.find(l => /^npm\s+i\s+https?:\/\/pkg\.pr\.new\//i.test(l)) || | |
| lines.find(l => /^pnpm\s+add\s+https?:\/\/pkg\.pr\.new\//i.test(l)) || | |
| lines.find(l => /^yarn\s+add\s+https?:\/\/pkg\.pr\.new\//i.test(l)) || | |
| // Fallback to generic install lines if present | |
| lines.find(l => /^pnpm\s+add\s+/i.test(l)) || | |
| lines.find(l => /^npm\s+i\s+/i.test(l) || /^npm\s+install\s+/i.test(l)) || | |
| lines.find(l => /^yarn\s+add\s+/i.test(l)) || | |
| ''; | |
| // Best-effort extract the preview URL from output | |
| const previewUrl = | |
| lines.find(l => /https?:\/\/pkg\.pr\.new\/[^\s)]+/i.test(l))?.match(/https?:\/\/pkg\.pr\.new\/[^\s)]+/i)?.[0] || ''; | |
| const fallback = 'Could not auto-detect a one-line install command — see raw output below.'; | |
| const baseBody = ` | |
| ## 📦 Package Preview Published | |
| **${display}** has been published to **pkg.pr.new** for this PR, so reviewers can test changes without waiting for an official npm release. | |
| ${previewUrl ? `Preview link: ${previewUrl}\n` : ''} | |
| ### ✅ Install | |
| ${installLine ? `\`\`\`bash\n${installLine}\n\`\`\`` : fallback} | |
| ### ✅ Quick verification (CLI) | |
| \`\`\`bash | |
| vsync --version | |
| vsync --help | |
| \`\`\` | |
| ### 🔎 Raw publish output (for troubleshooting) | |
| <details> | |
| <summary>Show output</summary> | |
| \`\`\` | |
| ${out.slice(0, 12000)} | |
| \`\`\` | |
| </details> | |
| (This comment will be updated on new pushes.) | |
| `.trim(); | |
| // Since this job is matrix, keep ONE comment per package by using a package-specific marker | |
| const pkgMarker = `${marker}<!-- ${dir} -->`; | |
| const body = `${pkgMarker}\n${baseBody}`; | |
| const { owner, repo } = context.repo; | |
| const issue_number = context.issue.number; | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| owner, | |
| repo, | |
| issue_number, | |
| per_page: 100, | |
| }); | |
| const existing = comments.find(c => (c.body || '').includes(pkgMarker)); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner, | |
| repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number, | |
| body, | |
| }); | |
| } |