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: PR Comment - Run Enhanced Flow | |
on: | |
issue_comment: | |
types: [created] | |
permissions: | |
contents: write | |
pull-requests: write | |
concurrency: | |
group: pr-comment-enhanced-flow-${{ github.event.issue.number || github.run_id }} | |
cancel-in-progress: false | |
jobs: | |
run-enhanced-flow: | |
if: > | |
${{ github.event.issue.pull_request != null && (contains(github.event.comment.body, 'node test-enhanced-flow.js') || contains(github.event.comment.body, '/run-enhanced-flow') || contains(github.event.comment.body, 'autosnap')) }} | |
runs-on: ubuntu-latest | |
timeout-minutes: 120 | |
steps: | |
- name: Checkout PR head | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
ref: refs/pull/${{ github.event.issue.number }}/head | |
- name: Setup Node.js | |
uses: actions/setup-node@v4 | |
with: | |
node-version: 20 | |
cache: yarn | |
- name: Enable Corepack (Yarn) | |
run: corepack enable | |
- name: Remove npm lockfiles to avoid Yarn conflicts | |
shell: bash | |
run: | | |
rm -f package-lock.json || true | |
rm -f AutoSnap/package-lock.json || true | |
rm -f AutoSnap/tracewrightt/package-lock.json || true | |
- name: Install root dependencies (optional) | |
shell: bash | |
run: | | |
if [ -f yarn.lock ]; then | |
yarn install --frozen-lockfile || yarn install | |
else | |
echo 'No root yarn.lock, skipping' | |
fi | |
- name: Install AutoSnap dependencies | |
working-directory: AutoSnap | |
shell: bash | |
run: | | |
yarn install --frozen-lockfile || yarn install | |
- name: Install tracewrightt and build | |
working-directory: AutoSnap/tracewrightt | |
shell: bash | |
run: | | |
echo "🔧 Installing tracewrightt dependencies..." | |
yarn install --frozen-lockfile || yarn install | |
echo "🏗️ Building tracewrightt..." | |
yarn build || echo "⚠️ tracewrightt build failed, will fallback to ts-node at runtime" | |
- name: Install Playwright Chromium and system deps | |
working-directory: AutoSnap | |
shell: bash | |
run: | | |
npx playwright install --with-deps chromium | |
- name: Setup Python | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.11' | |
- name: Install Python requirements | |
working-directory: AutoSnap | |
shell: bash | |
run: | | |
python -m pip install --upgrade pip | |
pip install -r requirements.txt || echo "Python requirements install failed, script has fallbacks" | |
- name: Create CI clone of test-enhanced-flow.js and patch paths | |
working-directory: AutoSnap | |
shell: bash | |
run: | | |
cp test-enhanced-flow.js test-enhanced-flow-ci.js | |
# Patch hardcoded Windows fallback path(s) to repo-relative path for CI | |
sed -i "s#C:/Users/Rohith\.MR/test/HelpManualAutomationTest/docs/1-Getting-Started/addorg\.md#docs/1-Getting-Started/addorg.md#g" test-enhanced-flow-ci.js | |
# Ensure CI runs headless Chromium and not Chrome channel | |
sed -i "s/headless: false/headless: true/g" test-enhanced-flow-ci.js | |
sed -i "/channel: 'chrome',/d" test-enhanced-flow-ci.js | |
- name: Ensure Azure env defaults | |
shell: bash | |
run: | | |
: "${AZURE_OPENAI_API_KEY:=placeholder}" | |
: "${AZURE_OPENAI_ENDPOINT:=https://example.invalid/}" | |
echo "AZURE_OPENAI_API_KEY=$AZURE_OPENAI_API_KEY" >> $GITHUB_ENV | |
echo "AZURE_OPENAI_ENDPOINT=$AZURE_OPENAI_ENDPOINT" >> $GITHUB_ENV | |
- name: Extract command args from comment | |
id: parse | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const body = context.payload.comment.body || ''; | |
// Handle all formats: node test-enhanced-flow.js, /run-enhanced-flow, and autosnap | |
const reNode = /node\s+test-enhanced-flow\.js(?:\s+([\s\S]*))?/i; // capture everything after the command on the first line | |
const reRun = /\/run-enhanced-flow(?:\s+([\s\S]*))?/i; // capture everything after the command on the first line | |
const reAutosnap = /autosnap(?:\s+([\s\S]*))?/i; // capture everything after the autosnap command | |
let args = ''; | |
// Try to match node test-enhanced-flow.js format | |
let m = body.match(reNode); | |
if (m && m[1]) { | |
args = m[1].trim(); | |
} else { | |
// Try to match /run-enhanced-flow format | |
m = body.match(reRun); | |
if (m && m[1]) { | |
args = m[1].trim(); | |
} else { | |
// Try to match autosnap format | |
m = body.match(reAutosnap); | |
if (m && m[1]) { | |
args = m[1].trim(); | |
} | |
} | |
} | |
// Handle --scenario parameter by converting it to --mode | |
if (args.includes('--scenario')) { | |
args = args.replace(/--scenario\s+(\S+)/g, '--mode $1'); | |
} | |
core.setOutput('args', args); | |
- name: Run enhanced flow | |
id: run_flow | |
shell: bash | |
env: | |
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} | |
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} | |
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }} | |
REPORTSEARCH_API_KEY: ${{ secrets.REPORTSEARCH_API_KEY }} | |
LLM_PROVIDER: gemini | |
DISABLE_IMG_AS: "true" | |
run: | | |
args="${{ steps.parse.outputs.args }}" | |
if [ -n "$args" ]; then | |
echo "Running: node AutoSnap/test-enhanced-flow-ci.js $args" | |
node AutoSnap/test-enhanced-flow-ci.js $args 2>&1 | tee enhanced-flow-ci-run.log | |
else | |
echo "No args provided in comment. Running default: node AutoSnap/test-enhanced-flow-ci.js" | |
node AutoSnap/test-enhanced-flow-ci.js 2>&1 | tee enhanced-flow-ci-run.log | |
fi | |
# Check for special comment markers in the log (language validation failure or API overload) | |
if grep -q "--- GITHUB_COMMENT_START ---" enhanced-flow-ci-run.log; then | |
echo "Found special comment markers" | |
# Extract the comment between the markers | |
SPECIAL_COMMENT=$(awk '/--- GITHUB_COMMENT_START ---/{flag=1;next}/--- GITHUB_COMMENT_END ---/{flag=0}flag' enhanced-flow-ci-run.log) | |
# Check if it's a language validation error, translation mode error, or API overload | |
if echo "$SPECIAL_COMMENT" | grep -q "LANGUAGE SELECTION FAILED"; then | |
echo "Found language validation failure comment" | |
ERROR_TYPE="language_validation" | |
elif echo "$SPECIAL_COMMENT" | grep -q "TRANSLATION MODE ERROR"; then | |
echo "Found translation mode error comment" | |
ERROR_TYPE="translation_mode_error" | |
elif echo "$SPECIAL_COMMENT" | grep -q "API OVERLOAD"; then | |
echo "Found API overload comment" | |
ERROR_TYPE="api_overload" | |
else | |
echo "Found generic error comment" | |
ERROR_TYPE="generic_error" | |
fi | |
# Set output variables with the extracted comment | |
echo "has_special_comment=true" >> $GITHUB_OUTPUT | |
echo "error_type=$ERROR_TYPE" >> $GITHUB_OUTPUT | |
echo "special_comment<<EOF" >> $GITHUB_OUTPUT | |
echo "$SPECIAL_COMMENT" >> $GITHUB_OUTPUT | |
echo "EOF" >> $GITHUB_OUTPUT | |
else | |
echo "No special comments detected" | |
echo "has_special_comment=false" >> $GITHUB_OUTPUT | |
echo "error_type=none" >> $GITHUB_OUTPUT | |
fi | |
- name: Upload logs | |
uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: enhanced-flow-logs | |
path: | | |
enhanced-flow-ci-run.log | |
enhanced-flow-log.txt | |
if-no-files-found: ignore | |
- name: Fail workflow if critical error occurred | |
if: steps.run_flow.outputs.has_special_comment == 'true' && (steps.run_flow.outputs.error_type == 'language_validation' || steps.run_flow.outputs.error_type == 'translation_mode_error' || steps.run_flow.outputs.error_type == 'generic_error') | |
shell: bash | |
run: | | |
if [[ "${{ steps.run_flow.outputs.error_type }}" == "language_validation" ]]; then | |
echo "::error::Language validation failed. The language code does not match any available option in the website." | |
elif [[ "${{ steps.run_flow.outputs.error_type }}" == "translation_mode_error" ]]; then | |
echo "::error::Translation mode error. English was specified as the target language in translation mode." | |
elif [[ "${{ steps.run_flow.outputs.error_type }}" == "generic_error" ]]; then | |
echo "::error::A critical error occurred during execution." | |
fi | |
exit 1 | |
- name: Get PR head info | |
id: pr_info | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const pr = await github.rest.pulls.get({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
pull_number: context.issue.number, | |
}); | |
core.setOutput('head_ref', pr.data.head.ref); | |
core.setOutput('head_repo', pr.data.head.repo.full_name); | |
const canPush = pr.data.head.repo.full_name === `${context.repo.owner}/${context.repo.repo}`; | |
core.setOutput('can_push', canPush ? 'true' : 'false'); | |
- name: Commit screenshots and markdown to PR branch | |
if: ${{ steps.pr_info.outputs.can_push == 'true' }} | |
shell: bash | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
HEAD_REPO: ${{ steps.pr_info.outputs.head_repo }} | |
HEAD_REF: ${{ steps.pr_info.outputs.head_ref }} | |
run: | | |
set -e | |
git config user.name "github-actions[bot]" | |
git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
# Only add modified or new PNG and MD files | |
echo "Finding modified or new PNG and MD files..." | |
# Find modified or new MD files | |
git diff --name-only --diff-filter=AMR | grep -E '\.md$|\.mdx$' | xargs -r git add | |
# Find modified or new PNG files | |
git diff --name-only --diff-filter=AMR | grep -E '\.png$' | xargs -r git add | |
# Show what will be committed | |
echo "Files to be committed:" | |
git status --short | |
# Check if there are changes to commit | |
if git diff --staged --quiet; then | |
echo "No changes to commit." | |
exit 0 | |
fi | |
# Commit and push | |
git commit -m "chore(ci): add screenshots and update markdown from enhanced flow run [skip ci]" | |
git push "https://x-access-token:${GITHUB_TOKEN}@github.com/${HEAD_REPO}.git" HEAD:${HEAD_REF} | |
- name: Reply on PR with run summary | |
if: always() | |
uses: actions/github-script@v7 | |
with: | |
script: | | |
const args = `${{ steps.parse.outputs.args }}` || '(none)'; | |
const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; | |
// Check if there's a special comment to include | |
const hasSpecialComment = '${{ steps.run_flow.outputs.has_special_comment }}' === 'true'; | |
const errorType = '${{ steps.run_flow.outputs.error_type }}'; | |
let bodyContent = [ | |
`▶️ Ran: node test-enhanced-flow.js ${args}`.trim(), | |
`(equivalent to: autosnap ${args})`, | |
`• Status: ${process.env.STATE || 'completed (see job result above)'}`, | |
`• Logs & outputs uploaded as artifact: enhanced-flow-artifacts`, | |
`• Workflow run: ${runUrl}` | |
]; | |
// Add special comment if present | |
if (hasSpecialComment) { | |
const specialComment = `${{ steps.run_flow.outputs.special_comment }}`; | |
bodyContent.push('\n---\n'); | |
bodyContent.push(specialComment); | |
// Add specific advice based on error type | |
if (errorType === 'language_validation') { | |
bodyContent.push('\nPlease check the language code and try again with a supported language.'); | |
} else if (errorType === 'translation_mode_error') { | |
bodyContent.push('\nPlease use a non-English target language with translation mode (e.g., --lang es for Spanish).'); | |
} else if (errorType === 'api_overload') { | |
bodyContent.push('\nThis is a temporary issue with the API service. Please try again in a few minutes.'); | |
} | |
} | |
await github.rest.issues.createComment({ | |
owner: context.repo.owner, | |
repo: context.repo.repo, | |
issue_number: context.issue.number, | |
body: bodyContent.join('\n') | |
}); | |