Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions .github/scripts/preview/comment-preview-urls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=.github/scripts/preview/common.sh
source "${SCRIPT_DIR}/common.sh"

require_env_vars \
GITHUB_TOKEN \
GITHUB_API_URL \
GITHUB_REPOSITORY \
PR_NUMBER \
API_URL \
UI_URL

COMMENT_MARKER="<!-- preview-environments:stable-urls -->"
COMMENTS_ENDPOINT="${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments"
API_HEALTH_URL="${API_URL%/}/health"
COMMENT_BODY_FILE="$(mktemp)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 Consider: Add cleanup trap for temp file

Issue: The temporary file created with mktemp is not explicitly cleaned up on exit.

Why: While GitHub Actions runners are ephemeral and the file will be deleted when the runner terminates, explicit cleanup is a best practice and improves local testability of the script.

Fix: Add a trap after this line:

trap 'rm -f "${COMMENT_BODY_FILE}"' EXIT

Refs:


cat > "${COMMENT_BODY_FILE}" <<EOF
${COMMENT_MARKER}
## Preview URLs

Use these stable preview aliases for testing this PR:

- UI: [${UI_URL}](${UI_URL})
- API: [${API_URL}](${API_URL})
- API health: [${API_HEALTH_URL}](${API_HEALTH_URL})

These point to the same Vercel preview deployment as the bot comment, but they stay stable and easier to find.
EOF

if [ -n "${UI_DEPLOYMENT_URL:-}" ] || [ -n "${API_DEPLOYMENT_URL:-}" ]; then
{
echo
echo "<details>"
echo "<summary>Raw Vercel deployment URLs</summary>"
echo
if [ -n "${UI_DEPLOYMENT_URL:-}" ]; then
echo "- UI deployment: [${UI_DEPLOYMENT_URL}](${UI_DEPLOYMENT_URL})"
fi
if [ -n "${API_DEPLOYMENT_URL:-}" ]; then
echo "- API deployment: [${API_DEPLOYMENT_URL}](${API_DEPLOYMENT_URL})"
fi
echo "</details>"
} >> "${COMMENT_BODY_FILE}"
fi

COMMENTS_JSON="$(
curl --connect-timeout 10 --max-time 30 -fsS \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
"${COMMENTS_ENDPOINT}?per_page=100"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💭 Consider: Pagination limited to 100 comments

Issue: The GitHub API comments endpoint is paginated and the query fetches only per_page=100. If a PR has more than 100 comments, the existing preview URLs comment might not be found, leading to duplicate comments instead of an upsert.

Why: While uncommon, PRs with extensive discussion or automated bot activity could exceed this limit. The jq query correctly selects the last matching comment, but if the marker comment isn't in the first 100, it won't be found.

Fix: This is a known edge case that's acceptable for most PRs. If you want complete coverage, you'd need to iterate through pages. Alternatively, document this as a known limitation since busy PRs with 100+ comments are rare.

Refs:

)"

EXISTING_COMMENT_ID="$(
jq -r \
--arg marker "${COMMENT_MARKER}" \
'[.[] | select(.user.login == "github-actions[bot]" and (.body | contains($marker)))] | last | .id // empty' \
<<< "${COMMENTS_JSON}"
)"

COMMENT_PAYLOAD="$(jq -Rs '{body: .}' < "${COMMENT_BODY_FILE}")"

if [ -n "${EXISTING_COMMENT_ID}" ]; then
curl --connect-timeout 10 --max-time 30 -fsS \
-X PATCH \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
-H "Content-Type: application/json" \
"${COMMENTS_ENDPOINT}/${EXISTING_COMMENT_ID}" \
--data "${COMMENT_PAYLOAD}" >/dev/null
else
curl --connect-timeout 10 --max-time 30 -fsS \
-X POST \
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
-H "Accept: application/vnd.github+json" \
-H "Content-Type: application/json" \
"${COMMENTS_ENDPOINT}" \
--data "${COMMENT_PAYLOAD}" >/dev/null
fi
14 changes: 14 additions & 0 deletions .github/workflows/preview-environments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ on:

permissions:
contents: read
issues: write
pull-requests: write

concurrency:
Expand Down Expand Up @@ -291,6 +292,19 @@ jobs:
echo "Smoke checks failed"
exit 1

- name: Publish stable preview URLs
if: ${{ steps.smoke.outcome == 'success' }}
env:
GITHUB_TOKEN: ${{ github.token }}
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ needs.compute-context.outputs.pr_number }}
API_URL: ${{ needs.compute-context.outputs.api_url }}
UI_URL: ${{ needs.compute-context.outputs.ui_url }}
API_DEPLOYMENT_URL: ${{ needs.configure-vercel-preview.outputs.api_deployment_url }}
UI_DEPLOYMENT_URL: ${{ needs.configure-vercel-preview.outputs.ui_deployment_url }}
run: bash .github/scripts/preview/comment-preview-urls.sh

teardown-tier1:
name: Teardown Tier 1 (Railway)
runs-on: ubuntu-latest
Expand Down
Loading