Skip to content

Add GitHub Action to post Stainless docs preview link on PRs #11

Add GitHub Action to post Stainless docs preview link on PRs

Add GitHub Action to post Stainless docs preview link on PRs #11

Workflow file for this run

name: Docs Preview
on:
pull_request:
types: [opened, synchronize, reopened]
concurrency:
group: docs-preview-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
# Update this with your Stainless project name
STAINLESS_PROJECT: tiger-data-docs
jobs:
post-preview-link:
name: Post Preview Link
runs-on: ubuntu-latest
permissions:
pull-requests: write
checks: read
steps:
- name: Generate preview URL
id: preview-url
run: |
# Sanitize branch name for URL (replace special chars with hyphens)
BRANCH_NAME="${{ github.head_ref }}"
SANITIZED_BRANCH=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//' | sed 's/-$//' | tr '[:upper:]' '[:lower:]')
# Stainless preview URL pattern - adjust if your pattern differs
PREVIEW_URL="https://${STAINLESS_PROJECT}--${SANITIZED_BRANCH}.preview.stainless.dev"
echo "preview_url=$PREVIEW_URL" >> $GITHUB_OUTPUT
echo "branch=$SANITIZED_BRANCH" >> $GITHUB_OUTPUT
- name: Wait for Stainless deployment
uses: actions/github-script@v7
with:
script: |
const sha = context.payload.pull_request.head.sha;
const maxAttempts = 60; // 10 minutes max (60 * 10 seconds)
const delaySeconds = 10;
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
console.log(`Checking for Stainless deployment (attempt ${attempt}/${maxAttempts})...`);
const { data: checkRuns } = await github.rest.checks.listForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: sha
});
// Look for Stainless Docs Build check
const stainlessCheck = checkRuns.check_runs.find(check =>
check.name === 'Stainless Docs Build'
);
if (stainlessCheck) {
console.log(`Found check: ${stainlessCheck.name} - Status: ${stainlessCheck.status}, Conclusion: ${stainlessCheck.conclusion}`);
if (stainlessCheck.status === 'completed') {
if (stainlessCheck.conclusion === 'success') {
console.log('Stainless deployment completed successfully!');
return;
} else {
core.setFailed(`Stainless deployment failed with conclusion: ${stainlessCheck.conclusion}`);
return;
}
}
} else {
console.log('No Stainless check found yet...');
}
// Wait before next attempt
await new Promise(resolve => setTimeout(resolve, delaySeconds * 1000));
}
console.log('Timeout waiting for Stainless deployment, posting comment anyway');
- name: Comment preview link on PR
uses: actions/github-script@v7
with:
script: |
const prNumber = context.payload.pull_request.number;
const previewUrl = '${{ steps.preview-url.outputs.preview_url }}';
const branch = '${{ steps.preview-url.outputs.branch }}';
const sha = context.payload.pull_request.head.sha.substring(0, 7);
const commentMarker = '<!-- stainless-docs-preview -->';
const commentBody = `${commentMarker}
## 📚 Docs Preview
| Status | Link |
|--------|------|
| ✅ Build successful | [Preview Deployment](${previewUrl}) |
**Branch:** \`${branch}\`
**Commit:** \`${sha}\`
> 🕐 Preview deployments may take a few minutes to become available after the build completes.
`;
// Get existing comments
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber
});
// Find existing bot comment
const existingComment = comments.find(comment =>
comment.body && comment.body.includes(commentMarker)
);
if (existingComment) {
// Update existing comment
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existingComment.id,
body: commentBody
});
console.log('Updated existing preview comment');
} else {
// Create new comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: commentBody
});
console.log('Created new preview comment');
}