Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sonar analysis for pull requests from forks #355

Closed
codyebberson opened this issue Feb 4, 2022 · 5 comments
Closed

Sonar analysis for pull requests from forks #355

codyebberson opened this issue Feb 4, 2022 · 5 comments

Comments

@codyebberson
Copy link
Member

codyebberson commented Feb 4, 2022

When someone opens a pull request from a fork (i.e., outside of the medplum/medplum repo), then the build fails. That is because Github Actions does not share Github secrets for forked PR's, so SONAR_TOKEN is not available, and the SonarCloud step fails.

We experimented with changing pull_request to pull_request_target, as described here, but that has security risks. A bad actor could submit a PR that completely changes the build scripts to perform an escalation attack as described here. This was reverted back to pull_request.

The "right" fix requires the following:

  • Separate build.yml into two actions
  • First, the build step that builds and tests, triggered by pull_request, which does not share any secrets
  • Second, an analysis step, triggered by workflow_run, which sends data to Sonar and Coveralls

This will require some experimentation. As others have found, the env variables in workflow_run are a weird hybrid of PR values and main branch values.

@codyebberson
Copy link
Member Author

This will be complicated. Need to stitch together a few high level concepts. Taking notes...

When the build is complete, upload the code coverage data. Something like this:

name: Upload data

on:
  pull_request:

jobs:
  upload:
    runs-on: ubuntu-latest

    steps:        
      - name: Save PR number
        env:
          PR_NUMBER: ${{ github.event.number }}
        run: |
          mkdir -p ./pr
          echo $PR_NUMBER > ./pr/pr_number
      - uses: actions/upload-artifact@v2
        with:
          name: pr_number
          path: pr/

(source: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run)

Then, in the analysis step, download the code coverage data. Something like this:

jobs:
  download:
    runs-on: ubuntu-latest
    steps:
      - name: 'Download artifact'
        uses: actions/github-script@v5
        with:
          script: |
            let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
               owner: context.repo.owner,
               repo: context.repo.repo,
               run_id: context.payload.workflow_run.id,
            });
            let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => {
              return artifact.name == "pr_number"
            })[0];
            let download = await github.rest.actions.downloadArtifact({
               owner: context.repo.owner,
               repo: context.repo.repo,
               artifact_id: matchArtifact.id,
               archive_format: 'zip',
            });
            let fs = require('fs');
            fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data));

      - name: 'Unzip artifact'
        run: unzip pr_number.zip

Explicitly checkout the PR branch, not the main branch:

steps:
  - uses: actions/checkout@v2
    with:
      ref: ${{ github.event.workflow_run.head_branch }}
  - run: git branch
  - run: env

(source: https://stackoverflow.com/questions/63343937/how-to-use-the-github-actions-workflow-run-event)

Explicitly set sonar properties

sonar.pullrequest.key: ${{ github.event.workflow_run.pull_requests.number }}
sonar.pullrequest.branch: ${{ github.event.workflow_run.pull_requests.head.ref }}
sonar.pullrequest.base: ${{ github.event.workflow_run.pull_requests.base.ref }}

(source: https://github.com/data-integrations/azure/actions/runs/796666446/workflow)

@codyebberson
Copy link
Member Author

@codyebberson
Copy link
Member Author

@codyebberson
Copy link
Member Author

This PR proves that it works!

#358

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant