Skip to content

RG-T133 User Session, Password Reset Changes, More Audits #187

RG-T133 User Session, Password Reset Changes, More Audits

RG-T133 User Session, Password Reset Changes, More Audits #187

name: Sync PR to Changerawr
permissions:
contents: read
issues: write
pull-requests: read
on:
pull_request:
types:
- closed
branches:
- master
jobs:
post-to-changerawr:
# Only run if the PR was merged (not just closed)
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 10
- name: Extract and prepare release notes
id: prepare_notes
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
set -euo pipefail
echo "Fetching PR #${PR_NUMBER} details..."
# Fetch the PR body using GitHub CLI
PR_BODY="$(gh pr view "$PR_NUMBER" --json body --jq '.body' 2>/dev/null || echo "")"
export PR_BODY
# Strip CodeRabbit content and pull out the Release Notes section
NOTES="$(python3 <<'PY'
import os, re
body = os.environ.get("PR_BODY", "")
# 1. Drop the whole CodeRabbit auto-generated block (start marker .. end marker)
body = re.sub(
r"<!--\s*This is an auto-generated comment: release notes by coderabbit\.ai\s*-->"
r".*?"
r"<!--\s*end of auto-generated comment: release notes by coderabbit\.ai\s*-->",
"",
body,
flags=re.IGNORECASE | re.DOTALL,
)
# 2. Drop any remaining HTML comments (covers unpaired/renamed markers)
body = re.sub(r"<!--.*?-->", "", body, flags=re.DOTALL)
# 3. Drop a leftover "Summary by CodeRabbit" section: heading -> next h1/h2 or EOF
body = re.sub(
r"^#{1,6}\s*Summary by CodeRabbit\b.*?(?=^#{1,2}\s|\Z)",
"",
body,
flags=re.IGNORECASE | re.MULTILINE | re.DOTALL,
)
# 4. Prefer an explicit "Release Notes" section when the author wrote one
m = re.search(
r"^#{1,6}\s*Release Notes\s*$\n(?P<notes>.*?)(?=^#{1,2}\s|\Z)",
body,
flags=re.IGNORECASE | re.MULTILINE | re.DOTALL,
)
notes = m.group("notes") if m and m.group("notes").strip() else body
# Collapse runs of blank lines and trim
notes = re.sub(r"\n{3,}", "\n\n", notes).strip()
print(notes)
PY
)"
# Fallback to PR title and recent commits if nothing usable remains
if [ -z "${NOTES//[[:space:]]/}" ]; then
echo "No usable PR body found, using PR title and commits..."
NOTES="## ${PR_TITLE}"
NOTES="$NOTES"$'\n\n'"$(git log -n 5 --pretty=format:'- %s')"
fi
# Save to file and step output
printf '%s\n' "$NOTES" > release_notes.txt
# For multiline output, use a delimiter that cannot appear in the content
DELIM="RELEASE_NOTES_EOF_$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')"
{
echo "RELEASE_NOTES<<${DELIM}"
printf '%s\n' "$NOTES"
echo "${DELIM}"
} >> "$GITHUB_OUTPUT"
echo "Release notes prepared:"
cat release_notes.txt
- name: Post to Changerawr API
uses: actions/github-script@v7
env:
CHANGERAWR_API_KEY: ${{ secrets.CHANGERAWR_API_KEY }}
CHANGERAWR_PROJECT_ID: ${{ secrets.CHANGERAWR_PROJECT_ID }}
RELEASE_NOTES: ${{ steps.prepare_notes.outputs.RELEASE_NOTES }}
with:
script: |
const prNumber = context.payload.pull_request.number;
const prTitle = context.payload.pull_request.title;
const prUrl = context.payload.pull_request.html_url;
const releaseNotes = process.env.RELEASE_NOTES || '';
// Check if required secrets are set
if (!process.env.CHANGERAWR_API_KEY || !process.env.CHANGERAWR_PROJECT_ID) {
console.log('⚠️ Changerawr API credentials not configured, skipping release notes submission');
return;
}
// Prepare the payload for Changerawr API
const payload = {
title: prTitle,
content: releaseNotes,
metadata: {
pr_number: prNumber,
pr_title: prTitle,
pr_url: prUrl,
merged_at: context.payload.pull_request.merged_at,
merged_by: context.payload.pull_request.merged_by?.login || 'unknown',
commit_sha: context.payload.pull_request.merge_commit_sha
}
};
console.log('Sending release notes to Changerawr...');
console.log('Payload:', JSON.stringify(payload, null, 2));
try {
const response = await fetch(
`https://clog.resgrid.com/api/projects/${process.env.CHANGERAWR_PROJECT_ID}/changelog`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.CHANGERAWR_API_KEY}`
},
body: JSON.stringify(payload)
}
);
const responseText = await response.text();
if (!response.ok) {
console.warn(`⚠️ Changerawr API request failed: ${response.status} - ${responseText}`);
// Don't fail the workflow, just log the error
return;
}
let result;
try {
result = JSON.parse(responseText);
} catch (e) {
result = responseText;
}
console.log('✅ Successfully posted to Changerawr:', result);
// Optionally, comment on the PR with confirmation
try {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
body: '✅ Change notes have been posted to Changerawr.'
});
} catch (commentError) {
console.log('Could not post comment to PR:', commentError.message);
}
} catch (error) {
console.error('⚠️ Error posting to Changerawr:', error);
// Don't fail the workflow
}