|
1 |
| -name: Check and publish security advisories |
| 1 | +name: Check advisories |
2 | 2 | on:
|
3 |
| - workflow_call: |
4 |
| - inputs: |
5 |
| - fetch-key: |
6 |
| - required: true |
7 |
| - type: string |
8 |
| - is-artifact: |
9 |
| - required: true |
10 |
| - type: boolean |
11 |
| - changed-advisories: |
12 |
| - required: false |
13 |
| - type: string |
14 |
| - default: '[]' |
| 3 | + - pull_request |
15 | 4 | jobs:
|
16 |
| - check-advisories: |
17 |
| - runs-on: ubuntu-20.04 |
| 5 | + tools_changed: |
| 6 | + continue-on-error: true |
| 7 | + runs-on: ubuntu-22.04 |
| 8 | + outputs: |
| 9 | + should_skip: ${{ steps.skip_check.outputs.should_skip }} |
18 | 10 | steps:
|
19 |
| - - uses: actions/checkout@v3 |
| 11 | + - id: skip_check |
| 12 | + |
20 | 13 | with:
|
21 |
| - path: source |
22 |
| - # We need to retrieve full history to determine the correct |
23 |
| - # `published` and `modified` timestamps |
24 |
| - fetch-depth: 0 |
25 |
| - - run: mkdir -p ~/.local/dockerImages |
26 |
| - - name: Fetch artifact |
27 |
| - if: ${{ inputs.is-artifact }} |
28 |
| - uses: actions/download-artifact@v3 |
29 |
| - with: |
30 |
| - name: ${{ inputs.fetch-key }} |
31 |
| - path: ~/.local/dockerImages |
32 |
| - - name: Fetch cache |
33 |
| - if: ${{ !inputs.is-artifact }} |
34 |
| - uses: actions/cache/restore@v3 |
| 14 | + concurrent_skipping: "never" |
| 15 | + skip_after_successful_duplicate: "true" |
| 16 | + paths: '["code/**"]' |
| 17 | + do_not_skip: '["push", "workflow_dispatch", "schedule"]' |
| 18 | + advisories_changed: |
| 19 | + continue-on-error: true |
| 20 | + runs-on: ubuntu-22.04 |
| 21 | + outputs: |
| 22 | + should_skip: ${{ steps.skip_check.outputs.should_skip }} |
| 23 | + changed_files: ${{ steps.process-changed-files.outputs.out }} |
| 24 | + steps: |
| 25 | + - id: skip_check |
| 26 | + |
35 | 27 | with:
|
36 |
| - key: ${{ inputs.fetch-key }} |
37 |
| - path: ~/.local/dockerImages |
38 |
| - fail-on-cache-miss: true |
39 |
| - - run: docker load -i ~/.local/dockerImages/hsec-tools |
40 |
| - - name: Run advisory syntax checks |
| 28 | + concurrent_skipping: "never" |
| 29 | + skip_after_successful_duplicate: "true" |
| 30 | + paths: '["advisories/**", "EXAMPLE_ADVISORY.md"]' |
| 31 | + do_not_skip: '["push", "workflow_dispatch", "schedule"]' |
| 32 | + - id: process-changed-files |
| 33 | + name: Extract matched files list |
41 | 34 | env:
|
42 |
| - CHANGED_ADVISORIES_JSON: ${{ inputs.changed-advisories }} |
43 |
| - run: | |
44 |
| - CHANGED_ADVISORIES=( $(printenv CHANGED_ADVISORIES_JSON | jq -r '.[]') ) |
45 |
| - cd source |
46 |
| - RESULT=0 |
47 |
| - # Remove the begining of the README to extract the example. |
48 |
| - (echo '```toml'; sed -e '1,/```toml/d' README.md) > EXAMPLE_README.md |
49 |
| - while read FILE ; do |
50 |
| - [ "$(dirname "$FILE")" != advisories/reserved ] || continue |
51 |
| - echo -n "$FILE: " |
52 |
| - docker run --rm -v $PWD:/repo --workdir /repo haskell/hsec-tools:latest /bin/hsec-tools check "$FILE" || RESULT=1 |
53 |
| - done < <([ ${#CHANGED_ADVISORIES[@]} -gt 0 ] && printf "%s\n" "${CHANGED_ADVISORIES[@]}" || find advisories EXAMPLE_README.md EXAMPLE_ADVISORY.md -type f -name "*.md") |
54 |
| - exit $RESULT |
55 |
| - - name: Run advisory uniqueness checks |
| 35 | + PATHS_RESULT: ${{ steps.skip_check.outputs.paths_result }} |
56 | 36 | run: |
|
57 |
| - ! find source/advisories -type f -name '*.md' -print0 \ |
58 |
| - | xargs -0n1 basename | sort | uniq -c | grep -E -v '[[:space:]]*1 ' |
59 |
| - - name: Publish OSV data |
60 |
| - if: ${{ github.event_name == 'push' && github.ref_name == 'main' && github.repository == 'haskell/security-advisories' }} |
61 |
| - env: |
62 |
| - GITHUB_SHA: ${{ github.sha }} |
| 37 | + echo -n 'out=' >> "$GITHUB_OUTPUT" |
| 38 | + # See https://github.com/fkirc/skip-duplicate-actions#paths_result |
| 39 | + printenv PATHS_RESULT \ |
| 40 | + | jq --compact-output .global.matched_files >> "$GITHUB_OUTPUT" |
| 41 | + code_hash: |
| 42 | + name: Compute code directory hash |
| 43 | + runs-on: ubuntu-22.04 |
| 44 | + outputs: |
| 45 | + code_hash: ${{ steps.code-hash.outputs.code-hash }} |
| 46 | + steps: |
| 47 | + - name: git checkout |
| 48 | + uses: actions/checkout@v3 |
| 49 | + - id: code-hash |
63 | 50 | run: |
|
64 |
| - DATA_DIR=$PWD/osv |
65 |
| - mkdir "$DATA_DIR" |
66 |
| - cd source |
67 |
| - while read FILE ; do |
68 |
| - ID=$(basename "$FILE" .md) |
69 |
| - YEAR=$(echo "$ID" | cut -d - -f 2) |
70 |
| - mkdir -p $DATA_DIR/$YEAR |
71 |
| - docker run --rm -v $PWD:/repo --workdir /repo haskell/hsec-tools:latest /bin/hsec-tools osv "$FILE" > $DATA_DIR/$YEAR/$ID.json |
72 |
| - done < <(find advisories -type f -name "*.md") |
73 |
| - BRANCH=generated/osv-export |
74 |
| - REF=refs/remotes/origin/$BRANCH |
75 |
| - export GIT_WORK_TREE=$DATA_DIR |
76 |
| - git read-tree "$REF" |
77 |
| - git add --all --intent-to-add |
78 |
| - git diff --quiet && exit |
79 |
| - git add --all |
80 |
| - TREE=$(git write-tree) |
81 |
| - git config user.email [email protected] |
82 |
| - git config user.name "Haskell Security Response Team" |
83 |
| - COMMIT=$(git commit-tree "$TREE" -p "$REF" -m "$(date --utc --rfc-3339=seconds) ($GITHUB_SHA)") |
84 |
| - git push origin $COMMIT:$BRANCH |
| 51 | + code_hash=$(git rev-parse HEAD:code) |
| 52 | + echo "code-hash=$code_hash" >> "$GITHUB_OUTPUT" |
| 53 | + check_advisories: |
| 54 | + name: Invoke check-advisories workflow |
| 55 | + needs: [tools_changed, advisories_changed, code_hash] |
| 56 | + if: ${{ needs.tools_changed.outputs.should_skip == 'true' && needs.advisories_changed.outputs.should_skip != 'true' }} |
| 57 | + uses: ./.github/workflows/call-check-advisories.yml |
| 58 | + with: |
| 59 | + fetch-key: hsec-tools-${{ needs.code_hash.outputs.code_hash }} |
| 60 | + is-artifact: false |
| 61 | + changed-advisories: ${{ needs.advisories_changed.outputs.changed_files }} |
0 commit comments