diff --git a/.github/workflows/cargo-vet-pr-comment.yml b/.github/workflows/cargo-vet-pr-comment.yml new file mode 100644 index 0000000..ba9caa4 --- /dev/null +++ b/.github/workflows/cargo-vet-pr-comment.yml @@ -0,0 +1,137 @@ +# This workflow triggers after cargo-vet workflow has run. +# It adds a comment to the PR with the results of the cargo vet run. +# It first adds a comment if the cargo vet run fails, +# and updates the comment if the cargo vet run succeeds after having failed at least once. + +name: Cargo vet PR comment + +on: + workflow_run: + workflows: [cargo-vet] + types: + - completed + +permissions: + contents: read + pull-requests: write + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + + find-pr-comment: + # This job runs when the cargo-vet job fails or succeeds + # It will download the artifact from the failed job and post a comment on the PR + runs-on: ubuntu-latest + outputs: + comment-id: ${{ steps.get-comment-id.outputs.comment-id }} + pr-number: ${{ steps.get-pr-number.outputs.pr_number }} + if: github.event.workflow_run.event == 'pull_request' + steps: + - name: 'Download artifact' + uses: actions/download-artifact@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + name: pr + path: pr/ + run-id: ${{ github.event.workflow_run.id }} + + - name: 'Get PR number' + id: get-pr-number + run: echo "pr_number=$(cat ./pr/NR)" >> $GITHUB_OUTPUT + + - name: 'Find existing comment' + id: find-comment + uses: peter-evans/find-comment@v3 + with: + issue-number: ${{ steps.get-pr-number.outputs.pr_number }} + comment-author: 'github-actions[bot]' + body-includes: 'comment-tag: [cargo-vet]' + + - name: 'Get comment ID' + id: get-comment-id + if: ${{ steps.find-comment.outputs.comment-id != '' }} + run: echo "comment-id=${{ steps.find-comment.outputs.comment-id }}" >> $GITHUB_OUTPUT + + post-comment-failure: + # This job runs when the cargo-vet job fails + # It will download the artifact from the failed job and post a comment on the PR + runs-on: ubuntu-latest + needs: find-pr-comment + if: github.event.workflow_run.conclusion == 'failure' + steps: + - name: 'Comment on PR - Failure' + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ needs.find-pr-comment.outputs.comment-id }} + issue-number: ${{ needs.find-pr-comment.outputs.pr-number }} + body: | + # Cargo Vet Audit Failed + + `cargo vet` has failed in this PR. Please run `cargo vet --locked` locally to check for new or updated unvetted dependencies. + Details about the vetting process can be found in [supply-chain/README.md](../blob/main/supply-chain/README.md) + + ## If the unvetted dependencies are not needed + Please modify Cargo.toml file to avoid including the dependencies. + + ## If the unvetted dependencies are needed + Post a new comment with the questionnaire below to the PR to help the auditors vet the dependencies. + After the auditors have vetted the dependencies, the PR will need to be rebased to pick up the new audits and pass this check. + + ### Copy and paste the questionnaire as a new comment and provide your answers: + + **1. What crates (with version) need to be audited?** + + **2. How many of the crates are version updates vs new dependencies?** + + **3. To confirm none of the already included crates serve your needs, please provide a brief description of the purpose of the new crates.** + + **4. Any extra notes to the auditors to help with their audits.** + + + edit-mode: replace + + - name: 'Label PR' + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.addLabels({ + issue_number: ${{ needs.find-pr-comment.outputs.pr-number }}, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['cargo vet'] + }) + + post-comment-success: + # This job runs when the cargo-vet job succeeds + # It will update the comment on the PR with a success message + runs-on: ubuntu-latest + needs: find-pr-comment + if: github.event.workflow_run.conclusion == 'success' + steps: + - name: 'Comment on PR - Success' + # Only update the comment if it exists + # This is to avoid creating a new comment if the cargo-vet job has never failed before + if: ${{ needs.find-pr-comment.outputs.comment-id }} + uses: peter-evans/create-or-update-comment@v4 + with: + comment-id: ${{ needs.find-pr-comment.outputs.comment-id }} + issue-number: ${{ needs.find-pr-comment.outputs.pr-number }} + body: | + # Cargo Vet Audit Passed + `cargo vet` has passed in this PR. No new unvetted dependencies were found. + + + edit-mode: replace diff --git a/.github/workflows/cargo-vet.yml b/.github/workflows/cargo-vet.yml new file mode 100644 index 0000000..8d825aa --- /dev/null +++ b/.github/workflows/cargo-vet.yml @@ -0,0 +1,53 @@ +# This workflow runs whenever a PR is opened or updated. It runs cargo vet to check for unvetted dependencies in the Cargo.lock file. +permissions: + contents: read +on: + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +name: cargo-vet +jobs: + vet: + # cargo-vet checks for unvetted dependencies in the Cargo.lock file + # This is to ensure that new dependencies are vetted before they are added to the project + name: vet-dependencies + runs-on: ubuntu-latest + env: + CARGO_VET_VERSION: 0.10.1 + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - uses: actions/cache@v4 + with: + path: ${{ runner.tool_cache }}/cargo-vet + key: cargo-vet-bin-${{ env.CARGO_VET_VERSION }} + + - name: Add the tool cache directory to the search path + run: echo "${{ runner.tool_cache }}/cargo-vet/bin" >> $GITHUB_PATH + + - name: Ensure that the tool cache is populated with the cargo-vet binary + run: cargo install --root ${{ runner.tool_cache }}/cargo-vet --version ${{ env.CARGO_VET_VERSION }} cargo-vet + + - name: Invoke cargo-vet + run: cargo vet --locked + + - name: Save PR number + # PR number is saved as an artifact so it can be used to determine the PR to comment on by the vet-pr-comment workflow + # vet-pr-comment workflow is triggered by the workflow_run event so it runs in the context of the base branch and not the PR branch + if: ${{ failure() }} || ${{ success() }} + run: | + mkdir -p ./pr + echo ${{ github.event.number }} > ./pr/NR + - uses: actions/upload-artifact@v4 + # Need to upload the artifact in both success and failure cases so comment can be updated in either case + if: ${{ failure() }} || ${{ success() }} + with: + name: pr + path: pr/ + overwrite: true diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml new file mode 100644 index 0000000..bb0e94c --- /dev/null +++ b/supply-chain/audits.toml @@ -0,0 +1,3 @@ +# cargo-vet audits file + +[audits] diff --git a/supply-chain/config.toml b/supply-chain/config.toml new file mode 100644 index 0000000..f5150e2 --- /dev/null +++ b/supply-chain/config.toml @@ -0,0 +1,13 @@ +# cargo-vet config file + +[cargo-vet] +version = "0.10" + +[imports.OpenDevicePartnership] +url = "https://raw.githubusercontent.com/OpenDevicePartnership/rust-crate-audits/main/audits.toml" + +[imports.google] +url = "https://raw.githubusercontent.com/google/rust-crate-audits/main/audits.toml" + +[imports.mozilla] +url = "https://raw.githubusercontent.com/mozilla/supply-chain/main/audits.toml" diff --git a/supply-chain/imports.lock b/supply-chain/imports.lock new file mode 100644 index 0000000..04903c1 --- /dev/null +++ b/supply-chain/imports.lock @@ -0,0 +1,7 @@ +# cargo-vet imports lock + +[audits.OpenDevicePartnership.audits] + +[audits.google.audits] + +[audits.mozilla.audits]