[llvm] workflows: Add a job for auditing release assets (PR #92829)

Tom Stellard via llvm-commits llvm-commits at lists.llvm.org
Tue May 21 09:16:38 PDT 2024


https://github.com/tstellar updated https://github.com/llvm/llvm-project/pull/92829

>From ab0cea7d95f6313bebf57a2984d1593800ba149c Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Mon, 20 May 2024 09:25:07 -0700
Subject: [PATCH 1/6] workflows: Add a job for auditing release assets

This checks to ensure that uploads are only made by 'approved'
uploaders, which is just everyone who has uploaded a release asset
in the past.

We could do more, but this is just a simple implementation so we
can put something in place and see how it works.

For more discussion see:
https://discourse.llvm.org/t/rfc-improve-binary-security/78121
---
 .github/workflows/release-asset-audit.py  | 40 ++++++++++++++++++++
 .github/workflows/release-asset-audit.yml | 45 +++++++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 .github/workflows/release-asset-audit.py
 create mode 100644 .github/workflows/release-asset-audit.yml

diff --git a/.github/workflows/release-asset-audit.py b/.github/workflows/release-asset-audit.py
new file mode 100644
index 0000000000000..02ba426293af6
--- /dev/null
+++ b/.github/workflows/release-asset-audit.py
@@ -0,0 +1,40 @@
+import github
+import sys
+
+token = sys.argv[1]
+
+gh = github.Github(login_or_token=token)
+repo = gh.get_repo('llvm/llvm-project')
+
+uploaders = set([
+    'DimitryAndric',
+    'stefanp-ibm',
+    'lei137',
+    'omjavaid',
+    'nicolerabjohn',
+    'amy-kwan',
+    'mandlebug',
+    'zmodem',
+    'androm3da',
+    'tru',
+    'rovka',
+    'rorth',
+    'quinnlp',
+    'kamaub',
+    'abrisco',
+    'jakeegan',
+    'maryammo',
+    'tstellar',
+    'github-actions[bot]'
+])
+
+for release in repo.get_releases():
+    print("Release:", release.title)
+    for asset in release.get_assets():
+        created_at = asset.created_at
+        updated_at = "" if asset.created_at == asset.updated_at else asset.updated_at
+        print(f'{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )')
+        if asset.uploader.login not in uploaders:
+          print("Invalid uploader")
+          sys.exit(1)
+
diff --git a/.github/workflows/release-asset-audit.yml b/.github/workflows/release-asset-audit.yml
new file mode 100644
index 0000000000000..9d140527218ff
--- /dev/null
+++ b/.github/workflows/release-asset-audit.yml
@@ -0,0 +1,45 @@
+name: Release Asset Audit
+
+on:
+  workflow_dispatch:
+  schedule:
+    # * is a special character in YAML so you have to quote this string
+    # Run once an hour
+    - cron:  '5 * * * *'
+
+  pull_request:
+    paths:
+      - ".github/workflows/release-asset-audit.py"
+      - ".github/workflows/release-asset-audit.yml"
+
+permissions:
+  contents: read # Default everything to read-only
+
+
+jobs:
+  audit:
+    name: "Release Asset Audit"
+    runs-on: ubuntu-22.04
+    if: github.repository == 'llvm/llvm-project'
+    steps:
+      - uses: actions/checkout at a5ac7e51b41094c92402da3b24376905380afc29 #v4.1.6
+      - name: "Run Audit Script"
+        env:
+          GITHUB_TOKEN: ${{ github.token }}
+        run: |
+          pip install --require-hashes -r ./llvm/utils/git/requirements.txt
+          python3 ./.github/workflows/release-asset-audit.py $GITHUB_TOKEN
+      - name: "File Issue"
+        if: failure()
+        uses: actions/github-script at 60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1
+        with:
+          github-token: ${{ secrets.ISSUE_SUBSCRIBER_TOKEN }}
+          script: |
+            const issue = await github.rest.issues.create({
+               owner: context.repo.owner,
+               repo: context.repo.repo,
+               title: "Release Asset Audit Failed",
+               body: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
+               labels: ['infrastructure']
+            });
+            console.log(issue);

>From f3ad45af0d4af0888655b80c2efdd3c1dfc8e5cd Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Mon, 20 May 2024 15:29:30 -0700
Subject: [PATCH 2/6] Fix python formatting

---
 .github/workflows/release-asset-audit.py | 54 +++++++++++++-----------
 1 file changed, 29 insertions(+), 25 deletions(-)

diff --git a/.github/workflows/release-asset-audit.py b/.github/workflows/release-asset-audit.py
index 02ba426293af6..4c793a754b952 100644
--- a/.github/workflows/release-asset-audit.py
+++ b/.github/workflows/release-asset-audit.py
@@ -4,37 +4,41 @@
 token = sys.argv[1]
 
 gh = github.Github(login_or_token=token)
-repo = gh.get_repo('llvm/llvm-project')
+repo = gh.get_repo("llvm/llvm-project")
 
-uploaders = set([
-    'DimitryAndric',
-    'stefanp-ibm',
-    'lei137',
-    'omjavaid',
-    'nicolerabjohn',
-    'amy-kwan',
-    'mandlebug',
-    'zmodem',
-    'androm3da',
-    'tru',
-    'rovka',
-    'rorth',
-    'quinnlp',
-    'kamaub',
-    'abrisco',
-    'jakeegan',
-    'maryammo',
-    'tstellar',
-    'github-actions[bot]'
-])
+uploaders = set(
+    [
+        "DimitryAndric",
+        "stefanp-ibm",
+        "lei137",
+        "omjavaid",
+        "nicolerabjohn",
+        "amy-kwan",
+        "mandlebug",
+        "zmodem",
+        "androm3da",
+        "tru",
+        "rovka",
+        "rorth",
+        "quinnlp",
+        "kamaub",
+        "abrisco",
+        "jakeegan",
+        "maryammo",
+        "tstellar",
+        "github-actions[bot]"
+    ]
+)
 
 for release in repo.get_releases():
     print("Release:", release.title)
     for asset in release.get_assets():
         created_at = asset.created_at
         updated_at = "" if asset.created_at == asset.updated_at else asset.updated_at
-        print(f'{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )')
+        print(
+            f"{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )"
+        )
         if asset.uploader.login not in uploaders:
-          print("Invalid uploader")
-          sys.exit(1)
+            print("Invalid uploader")
+            sys.exit(1)
 

>From a9806789b3aa0bf7a7d97fd04e3207bce5f29da6 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Mon, 20 May 2024 15:37:29 -0700
Subject: [PATCH 3/6] Fix formatting

---
 .github/workflows/release-asset-audit.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.github/workflows/release-asset-audit.py b/.github/workflows/release-asset-audit.py
index 4c793a754b952..e7bf77097b367 100644
--- a/.github/workflows/release-asset-audit.py
+++ b/.github/workflows/release-asset-audit.py
@@ -26,7 +26,7 @@
         "jakeegan",
         "maryammo",
         "tstellar",
-        "github-actions[bot]"
+        "github-actions[bot]",
     ]
 )
 
@@ -41,4 +41,3 @@
         if asset.uploader.login not in uploaders:
             print("Invalid uploader")
             sys.exit(1)
-

>From 96107099ef213e59692abbf090b5ecf85abe11ad Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Mon, 20 May 2024 17:30:09 -0700
Subject: [PATCH 4/6] Move everything into a main function

---
 .github/workflows/release-asset-audit.py | 80 +++++++++++++-----------
 1 file changed, 43 insertions(+), 37 deletions(-)

diff --git a/.github/workflows/release-asset-audit.py b/.github/workflows/release-asset-audit.py
index e7bf77097b367..938244bda2c75 100644
--- a/.github/workflows/release-asset-audit.py
+++ b/.github/workflows/release-asset-audit.py
@@ -1,43 +1,49 @@
 import github
 import sys
 
-token = sys.argv[1]
+def main():
 
-gh = github.Github(login_or_token=token)
-repo = gh.get_repo("llvm/llvm-project")
+    token = sys.argv[1]
 
-uploaders = set(
-    [
-        "DimitryAndric",
-        "stefanp-ibm",
-        "lei137",
-        "omjavaid",
-        "nicolerabjohn",
-        "amy-kwan",
-        "mandlebug",
-        "zmodem",
-        "androm3da",
-        "tru",
-        "rovka",
-        "rorth",
-        "quinnlp",
-        "kamaub",
-        "abrisco",
-        "jakeegan",
-        "maryammo",
-        "tstellar",
-        "github-actions[bot]",
-    ]
-)
+    gh = github.Github(login_or_token=token)
+    repo = gh.get_repo("llvm/llvm-project")
 
-for release in repo.get_releases():
-    print("Release:", release.title)
-    for asset in release.get_assets():
-        created_at = asset.created_at
-        updated_at = "" if asset.created_at == asset.updated_at else asset.updated_at
-        print(
-            f"{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )"
-        )
-        if asset.uploader.login not in uploaders:
-            print("Invalid uploader")
-            sys.exit(1)
+    uploaders = set(
+        [
+            "DimitryAndric",
+            "stefanp-ibm",
+            "lei137",
+            "omjavaid",
+            "nicolerabjohn",
+            "amy-kwan",
+            "mandlebug",
+            "zmodem",
+            "androm3da",
+            "tru",
+            "rovka",
+            "rorth",
+            "quinnlp",
+            "kamaub",
+            "abrisco",
+            "jakeegan",
+            "maryammo",
+            "tstellar",
+            "github-actions[bot]",
+        ]
+    )
+
+    for release in repo.get_releases():
+        print("Release:", release.title)
+        for asset in release.get_assets():
+            created_at = asset.created_at
+            updated_at = "" if asset.created_at == asset.updated_at else asset.updated_at
+            print(
+                f"{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )"
+            )
+            if asset.uploader.login not in uploaders:
+                print("Invalid uploader")
+                sys.exit(1)
+
+
+if __name__ == '__main__':
+    main()

>From d9eb2a94d7f42af6887d51eb517c03a5752783f3 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Mon, 20 May 2024 17:38:07 -0700
Subject: [PATCH 5/6] Fix formatting

---
 .github/workflows/release-asset-audit.py | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/release-asset-audit.py b/.github/workflows/release-asset-audit.py
index 938244bda2c75..2ffe40d9d4bab 100644
--- a/.github/workflows/release-asset-audit.py
+++ b/.github/workflows/release-asset-audit.py
@@ -1,8 +1,8 @@
 import github
 import sys
 
-def main():
 
+def main():
     token = sys.argv[1]
 
     gh = github.Github(login_or_token=token)
@@ -36,7 +36,9 @@ def main():
         print("Release:", release.title)
         for asset in release.get_assets():
             created_at = asset.created_at
-            updated_at = "" if asset.created_at == asset.updated_at else asset.updated_at
+            updated_at = (
+                "" if asset.created_at == asset.updated_at else asset.updated_at
+            )
             print(
                 f"{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )"
             )
@@ -45,5 +47,5 @@ def main():
                 sys.exit(1)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main()

>From 4744a1042b3399fc5a1440ce12daf81b24c450ae Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Tue, 21 May 2024 06:23:42 -0700
Subject: [PATCH 6/6] Add a reason why the script failed

---
 .github/workflows/release-asset-audit.py  |  4 ++--
 .github/workflows/release-asset-audit.yml | 17 +++++++++++++----
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/release-asset-audit.py b/.github/workflows/release-asset-audit.py
index 2ffe40d9d4bab..355e7fee1dae0 100644
--- a/.github/workflows/release-asset-audit.py
+++ b/.github/workflows/release-asset-audit.py
@@ -1,7 +1,6 @@
 import github
 import sys
 
-
 def main():
     token = sys.argv[1]
 
@@ -43,7 +42,8 @@ def main():
                 f"{asset.name} : {asset.uploader.login} [{created_at} {updated_at}] ( {asset.download_count} )"
             )
             if asset.uploader.login not in uploaders:
-                print("Invalid uploader")
+                with open('comment', 'w') as file:
+                    file.write(f'@{asset.uploader.login} is not a valid uploader.')
                 sys.exit(1)
 
 
diff --git a/.github/workflows/release-asset-audit.yml b/.github/workflows/release-asset-audit.yml
index 9d140527218ff..fd42bc67b9997 100644
--- a/.github/workflows/release-asset-audit.yml
+++ b/.github/workflows/release-asset-audit.yml
@@ -2,6 +2,7 @@ name: Release Asset Audit
 
 on:
   workflow_dispatch:
+  release:
   schedule:
     # * is a special character in YAML so you have to quote this string
     # Run once an hour
@@ -15,7 +16,6 @@ on:
 permissions:
   contents: read # Default everything to read-only
 
-
 jobs:
   audit:
     name: "Release Asset Audit"
@@ -30,16 +30,25 @@ jobs:
           pip install --require-hashes -r ./llvm/utils/git/requirements.txt
           python3 ./.github/workflows/release-asset-audit.py $GITHUB_TOKEN
       - name: "File Issue"
-        if: failure()
+        if: >-
+          github.event_name != 'pull_request' &&
+          failure()
         uses: actions/github-script at 60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1
         with:
           github-token: ${{ secrets.ISSUE_SUBSCRIBER_TOKEN }}
           script: |
+            var fs = require('fs');
+            var body = ''
+            if (fs.existsSync('./comment')) {
+              body = JSON.parse(fs.readFileSync('./comment')) + "\n\n";
+            }
+            body = body + `\n\nhttps://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`
+
             const issue = await github.rest.issues.create({
                owner: context.repo.owner,
                repo: context.repo.repo,
                title: "Release Asset Audit Failed",
-               body: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
-               labels: ['infrastructure']
+               labels: ['infrastructure'],
+               body: body
             });
             console.log(issue);



More information about the llvm-commits mailing list