diff --git a/.github/workflows/docx-diff.yml b/.github/workflows/docx-diff.yml index 77ed7c2..a879189 100644 --- a/.github/workflows/docx-diff.yml +++ b/.github/workflows/docx-diff.yml @@ -5,7 +5,7 @@ name: TurboDocx DOCX Diff Report on: - pull_request_target: + pull_request: branches: - main - develop @@ -14,7 +14,7 @@ jobs: docx-diff: runs-on: ubuntu-latest permissions: - pull-requests: write # Needed to post PR comments + pull-requests: write # Needed to post PR comments contents: read steps: @@ -53,6 +53,7 @@ jobs: uses: actions/checkout@v5 with: path: current + persist-credentials: false - name: Setup Node.js for current uses: actions/setup-node@v5 @@ -77,26 +78,26 @@ jobs: id: diff working-directory: current run: | - node scripts/diff-docx.js ../baseline.docx ../current.docx --output ../diff-report.md || echo "diff_failed=true" >> $GITHUB_OUTPUT + node scripts/diff-docx.js ../baseline.docx ../current.docx --output diff-report.md || echo "diff_failed=true" >> $GITHUB_OUTPUT - name: Read TurboDocx diff report id: report run: | - if [ -f diff-report.md ]; then + if [ -f current/diff-report.md ]; then { echo 'report<> $GITHUB_OUTPUT fi - name: Post TurboDocx DOCX diff report as PR comment - if: steps.report.outputs.report != '' + if: steps.report.outputs.report != '' && github.event.pull_request.head.repo.full_name == github.repository uses: actions/github-script@v8 with: script: | const fs = require('fs'); - const report = fs.readFileSync('diff-report.md', 'utf8'); + const report = fs.readFileSync('current/diff-report.md', 'utf8'); // Find existing comment const comments = await github.rest.issues.listComments({ @@ -138,7 +139,7 @@ jobs: path: | baseline.docx current.docx - diff-report.md + current/diff-report.md retention-days: 30 - name: Verify DOCX regression test results diff --git a/tests/docx-diff-workflow.test.js b/tests/docx-diff-workflow.test.js new file mode 100644 index 0000000..a7e6849 --- /dev/null +++ b/tests/docx-diff-workflow.test.js @@ -0,0 +1,33 @@ +import fs from 'fs'; +import path from 'path'; + +const workflowPath = path.join(__dirname, '..', '.github', 'workflows', 'docx-diff.yml'); +const workflow = fs.readFileSync(workflowPath, 'utf8'); + +describe('DOCX diff workflow', () => { + test('runs pull request code in the unprivileged pull_request context', () => { + expect(workflow).toMatch(/^\s*pull_request:\s*$/m); + expect(workflow).not.toMatch(/^\s*pull_request_target:\s*$/m); + }); + + test('does not persist checkout credentials in the PR worktree', () => { + const currentCheckout = workflow.match(/- name: Checkout PR branch[\s\S]*?(?=\n\s{6}- name:)/); + + expect(currentCheckout).not.toBeNull(); + expect(currentCheckout[0]).toMatch(/persist-credentials:\s*false/); + }); + + test('keeps the report inside the current worktree and aligns every consumer', () => { + expect(workflow).toContain('working-directory: current'); + expect(workflow).toContain( + 'node scripts/diff-docx.js ../baseline.docx ../current.docx --output diff-report.md' + ); + expect(workflow.match(/current\/diff-report\.md/g)).toHaveLength(4); + }); + + test('posts comments only when the PR branch belongs to the base repository', () => { + expect(workflow).toContain( + "if: steps.report.outputs.report != '' && github.event.pull_request.head.repo.full_name == github.repository" + ); + }); +});