name: Comment Check Amalgamation
on:
  workflow_run:
    workflows: ["Check amalgamation"]
    types:
      - completed

permissions:
  contents: read

jobs:
  comment:
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    runs-on: ubuntu-latest
    permissions:
      contents: read
      actions: read
      issues: read
      pull-requests: write
    steps:
      - name: Harden Runner
        uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
        with:
          egress-policy: audit

      - name: 'Download artifact'
        id: download
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        with:
          script: |
            var artifacts = await github.rest.actions.listWorkflowRunArtifacts({
               owner: context.repo.owner,
               repo: context.repo.repo,
               run_id: ${{github.event.workflow_run.id }},
            });
            var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
              return artifact.name == "pr"
            })[0];
            var download = await github.rest.actions.downloadArtifact({
               owner: context.repo.owner,
               repo: context.repo.repo,
               artifact_id: matchArtifact.id,
               archive_format: 'zip',
            });
            var fs = require('fs');
            fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data));

            var hasPatch = artifacts.data.artifacts.some((artifact) => artifact.name == "amalgamation-patch");
            core.setOutput('has_patch', String(hasPatch));
      # Extract the untrusted PR artifact into a dedicated empty directory and
      # read only the two expected files by fixed path afterwards. This avoids a
      # malicious archive overwriting workspace files or escaping via ../ paths.
      - run: unzip -o pr.zip -d ./pr_artifact

      - name: 'Comment on PR'
        uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            var fs = require('fs');
            // Both values come from a fork-triggered workflow and are therefore
            // attacker-controlled. Validate them strictly before use to prevent
            // Markdown/mention injection and bogus REST API filters.
            const author = fs.readFileSync('./pr_artifact/author', 'utf8').trim();
            if (!/^[A-Za-z0-9-]{1,39}$/.test(author)) {
              core.setFailed(`Refusing to proceed: untrusted author value '${author}' is not a valid GitHub username.`);
              return;
            }
            const issue_number = Number(fs.readFileSync('./pr_artifact/number', 'utf8').trim());
            if (!Number.isInteger(issue_number) || issue_number <= 0) {
              core.setFailed('Refusing to proceed: untrusted PR number is not a positive integer.');
              return;
            }
            const opts = github.rest.issues.listForRepo.endpoint.merge({
              owner: context.repo.owner,
              repo: context.repo.repo,
              creator: author,
              state: 'all'
            })
            let first = true
            const issues = await github.paginate(opts)
            for (const issue of issues) {
              if (issue.number === issue_number) {
                continue
              }
              if (issue.pull_request) {
                first = false
                break
              }
            }
            const hasPatch = '${{ steps.download.outputs.has_patch }}' === 'true';
            const runUrl = '${{ github.event.workflow_run.html_url }}';

            await github.rest.issues.createComment({
              issue_number: issue_number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: '## 🔴 Amalgamation check failed! 🔴\nThe source code has not been amalgamated and/or formatted correctly.'
                    + (hasPatch ? '\n\n📎 A ready-to-apply patch is attached to the [failed workflow run](' + runUrl + ') as the `amalgamation-patch` artifact.'
                                  + ' Download it, then apply it locally from the repository root with:'
                                  + '\n\n```shell\ngit apply amalgamation.patch\n```\n\n'
                                  + 'This does not require installing astyle yourself.'
                                : '')
                    + (first ? '\n\n@' + author + ' Please read and follow the [Contribution Guidelines]'
                               + '(https://github.com/nlohmann/json/blob/develop/.github/CONTRIBUTING.md#files-to-change).'
                             : '')
              })
