Repository: electron/debian-sysroot-image-creator
Pull request #45: feat: add upstream `sysroot_scripts` monitoring
Author: login: codebytere
Created: 2025-03-13T19:00:54Z | Merged: 2025-03-17T19:38:23Z

This adds some auto-monitoring to prevent massive script drift. Action runs every two weeks.

Successful run: https://github.com/electron/debian-sysroot-image-creator/actions/runs/13907206614/job/38912955330

New issue: https://github.com/electron/debian-sysroot-image-creator/issues/54


Diff:
diff --git a/.github/workflows/upstream-sysroot.yml b/.github/workflows/upstream-sysroot.yml
new file mode 100644
index 0000000..a973c29
--- /dev/null
+++ b/.github/workflows/upstream-sysroot.yml
@@ -0,0 +1,84 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: false
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: false
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    env:
+      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+    steps:
+    - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+    - name: Fetch Current SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.current-sha }}" ]; then
+          CURRENT_SHA="${{ github.event.inputs.current-sha }}"
+        elif [ -f current-sha.json ]; then
+          CURRENT_SHA=$(jq -r '.sha' current-sha.json)
+        else
+          echo "No current SHA provided and current-sha.json not found."
+          exit 1
+        fi
+        echo "CURRENT_SHA=${CURRENT_SHA}" >> $GITHUB_ENV
+    - name: Fetch latest upstream SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.upstream-sha }}" ]; then
+          UPSTREAM_SHA="${{ github.event.inputs.upstream-sha }}"
+        else
+          UPSTREAM_SHA=$(gh api -X GET repos/chromium/chromium/commits -f path="build/linux/sysroot_scripts" -f per_page=1 --jq '.[0].sha')
+        fi
+        echo "UPSTREAM_SHA=${UPSTREAM_SHA}" >> $GITHUB_ENV
+    - name: Compare current SHA with upstream SHA
+      shell: bash
+      run: |
+        if [ "${{ env.CURRENT_SHA }}" == "${{ env.UPSTREAM_SHA }}" ]; then
+          echo "No changes found - sysroot scripts are up to date!"
+        else
+          gh api -X GET repos/chromium/chromium/commits -f path="build/linux/sysroot_scripts" -f per_page=20 > commits.json
+
+          COMMITS=$(
+            jq -r --arg base_sha "${{ env.CURRENT_SHA }}" '
+              ([.[].sha] | index($base_sha) // length) as $idx |
+              .[0:$idx] | .[] | 
+              "- [`\(.sha[0:7])`](\(.html_url)) \(.commit.message | split("\n")[0])"
+            ' commits.json
+          )
+
+          if [ -z "$COMMITS" ]; then
+            echo "No new commits found."
+            exit 0
+          fi
+
+          ISSUE_BODY=$(cat <<EOF
+        ### Upstream sysroot scripts have been updated
+
+        Commits between \`${CURRENT_SHA:0:7}\` and \`${UPSTREAM_SHA:0:7}\`:
+
+        ${COMMITS}
+
+        @electron/wg-upgrades please review these changes and update our scripts accordingly.
+        EOF
+          )
+
+          gh issue create --title "Upstream sysroot scripts have changed" --body="$ISSUE_BODY"
+        fi
diff --git a/current-sha.json b/current-sha.json
new file mode 100644
index 0000000..0621d77
--- /dev/null
+++ b/current-sha.json
@@ -0,0 +1,3 @@
+{
+  "sha": "082a46c99411023b97fae0476b526b54ff98aa3d" 
+}


Reviews:
user: login: ckerr
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-13T19:40:03Z
user: login: ckerr
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-13T19:41:15Z
user: login: dsanders11
body: Left a few comments, only two of which are blockers: need to use `actions/checkout` to be able to read `current-sha.json`, and need to handle the case where the upstream SHA does not match the current SHA but there have been no changes to `build/linux/sysroot_scripts` between those SHAs.

The other comments opt for using the `gh` CLI instead of raw curl calls since it's available to us automatically and you don't have to manually supply auth tokens or other arguments.

Final bit, just want to consider if an issue is the best output option here. For other audit workflows I've generally wired them up to output to the summary for the workflow. In this case I'm guessing an issue is desirable because it can be referenced in an associated PR to land the upstream changes?

Regardless of issue vs workflow summary as the output mechanism, I think we should also wire up a Slack message to fire so that we don't miss the output.
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-13T21:11:53Z
user: login: codebytere
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T21:17:33Z
user: login: dsanders11
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T21:43:31Z
user: login: codebytere
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T21:45:05Z
user: login: dsanders11
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-13T21:45:57Z
user: login: dsanders11
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-17T18:40:18Z

Review comments:
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: What's the imagined use case where these inputs are supplied by a maintainer, and are required inputs? It's always useful to be able to manually kick scheduled workflows so I get the `workflow_dispatch:` inclusion, just trying to think through why I'd want to manually kick it but have to supply the SHA values as inputs. Could these be made optional?
created_at: 2025-03-13T20:20:34Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
+    - name: Fetch Current SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.current-sha }}" ]; then
+          CURRENT_SHA="${{ github.event.inputs.current-sha }}"
+        elif [ -f current-sha.json ]; then
+          CURRENT_SHA=$(jq -r '.sha' current-sha.json)
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: The workflow needs to do a checkout for this file to be present.
created_at: 2025-03-13T20:22:38Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
+    - name: Fetch Current SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.current-sha }}" ]; then
+          CURRENT_SHA="${{ github.event.inputs.current-sha }}"
+        elif [ -f current-sha.json ]; then
+          CURRENT_SHA=$(jq -r '.sha' current-sha.json)
+        else
+          echo "No current SHA provided and current-sha.json not found."
+          exit 1
+        fi
+        echo "CURRENT_SHA=${CURRENT_SHA}" >> $GITHUB_ENV
+    - name: Fetch latest upstream SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.upstream-sha }}" ]; then
+          UPSTREAM_SHA="${{ github.event.inputs.upstream-sha }}"
+        else
+          UPSTREAM_SHA=$(curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=1" | jq -r '.[0].sha')
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: ```suggestion
          UPSTREAM_SHA=$(gh api -X GET repos/chromium/chromium/commits -f path="build/linux/sysroot_scripts" -f per_page=1 --jq '.[0].sha')
```

Slight change so it will automatically use the GH token.
created_at: 2025-03-13T20:37:59Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: ```suggestion
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
```

Makes the token available to `gh` CLI invocations in the steps.
created_at: 2025-03-13T20:38:58Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
+    - name: Fetch Current SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.current-sha }}" ]; then
+          CURRENT_SHA="${{ github.event.inputs.current-sha }}"
+        elif [ -f current-sha.json ]; then
+          CURRENT_SHA=$(jq -r '.sha' current-sha.json)
+        else
+          echo "No current SHA provided and current-sha.json not found."
+          exit 1
+        fi
+        echo "CURRENT_SHA=${CURRENT_SHA}" >> $GITHUB_ENV
+    - name: Fetch latest upstream SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.upstream-sha }}" ]; then
+          UPSTREAM_SHA="${{ github.event.inputs.upstream-sha }}"
+        else
+          UPSTREAM_SHA=$(curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=1" | jq -r '.[0].sha')
+        fi
+        echo "UPSTREAM_SHA=${UPSTREAM_SHA}" >> $GITHUB_ENV
+    - name: Compare current SHA with upstream SHA
+      shell: bash
+      run: |
+        if [ "${{ env.CURRENT_SHA }}" == "${{ env.UPSTREAM_SHA }}" ]; then
+          echo "No changes found - sysroot scripts are up to date!"
+        else
+          curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=20" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" > commits.json
+
+          COMMITS=$(
+            jq -r --arg base_sha "${{ env.CURRENT_SHA }}" '
+              ([.[].sha] | index($base_sha) // length) as $idx |
+              .[0:$idx] | .[] | 
+              "- [`\(.sha[0:7])`](\(.html_url)) \(.commit.message | split("\n")[0])"
+            ' commits.json
+          )
+
+          ISSUE_BODY=$(cat <<EOF
+        ### Upstream sysroot scripts have been updated
+
+        Commits between \`${CURRENT_SHA:0:7}\` and \`${UPSTREAM_SHA:0:7}\`:
+
+        ${COMMITS}
+
+        Please review these changes and update our scripts accordingly.
+        EOF
+          )
+
+          BODY_JSON=$(jq -n --arg body "$ISSUE_BODY" --arg title "Upstream sysroot scripts have changed" '{title: $title, body: $body}')
+
+          curl -X POST \
+            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
+            -H "Accept: application/vnd.github.v3+json" \
+            -H "Content-Type: application/json" \
+            -d "$BODY_JSON" \
+            "https://api.github.com/repos/${{ github.repository }}/issues"
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: ```suggestion
          printf $ISSUE_BODY | gh issue create --title "Upstream sysroot scripts have changed" --body-file=-
```

This is untested but based on https://github.com/electron/electron/blob/4a28e60e89919a569a24f1d37e0b0ad8ebc26071/.github/workflows/non-maintainer-dependency-change.yml#L37
created_at: 2025-03-13T20:47:00Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
+    - name: Fetch Current SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.current-sha }}" ]; then
+          CURRENT_SHA="${{ github.event.inputs.current-sha }}"
+        elif [ -f current-sha.json ]; then
+          CURRENT_SHA=$(jq -r '.sha' current-sha.json)
+        else
+          echo "No current SHA provided and current-sha.json not found."
+          exit 1
+        fi
+        echo "CURRENT_SHA=${CURRENT_SHA}" >> $GITHUB_ENV
+    - name: Fetch latest upstream SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.upstream-sha }}" ]; then
+          UPSTREAM_SHA="${{ github.event.inputs.upstream-sha }}"
+        else
+          UPSTREAM_SHA=$(curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=1" | jq -r '.[0].sha')
+        fi
+        echo "UPSTREAM_SHA=${UPSTREAM_SHA}" >> $GITHUB_ENV
+    - name: Compare current SHA with upstream SHA
+      shell: bash
+      run: |
+        if [ "${{ env.CURRENT_SHA }}" == "${{ env.UPSTREAM_SHA }}" ]; then
+          echo "No changes found - sysroot scripts are up to date!"
+        else
+          curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=20" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" > commits.json
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: ```suggestion
          gh api -X GET repos/chromium/chromium/commits -f path="build/linux/sysroot_scripts" -f per_page=20 > commits.json
```

Just a bit cleaner and matches the other suggested changes.
created_at: 2025-03-13T20:58:53Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
+    - name: Fetch Current SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.current-sha }}" ]; then
+          CURRENT_SHA="${{ github.event.inputs.current-sha }}"
+        elif [ -f current-sha.json ]; then
+          CURRENT_SHA=$(jq -r '.sha' current-sha.json)
+        else
+          echo "No current SHA provided and current-sha.json not found."
+          exit 1
+        fi
+        echo "CURRENT_SHA=${CURRENT_SHA}" >> $GITHUB_ENV
+    - name: Fetch latest upstream SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.upstream-sha }}" ]; then
+          UPSTREAM_SHA="${{ github.event.inputs.upstream-sha }}"
+        else
+          UPSTREAM_SHA=$(curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=1" | jq -r '.[0].sha')
+        fi
+        echo "UPSTREAM_SHA=${UPSTREAM_SHA}" >> $GITHUB_ENV
+    - name: Compare current SHA with upstream SHA
+      shell: bash
+      run: |
+        if [ "${{ env.CURRENT_SHA }}" == "${{ env.UPSTREAM_SHA }}" ]; then
+          echo "No changes found - sysroot scripts are up to date!"
+        else
+          curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=20" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" > commits.json
+
+          COMMITS=$(
+            jq -r --arg base_sha "${{ env.CURRENT_SHA }}" '
+              ([.[].sha] | index($base_sha) // length) as $idx |
+              .[0:$idx] | .[] | 
+              "- [`\(.sha[0:7])`](\(.html_url)) \(.commit.message | split("\n")[0])"
+            ' commits.json
+          )
+
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: I think we need to handle the case where after filtering, there were no new commits inside `build/linux/sysroot_scripts`?
created_at: 2025-03-13T21:10:19Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
path: .github/workflows/upstream-sysroot.yml
user: login: codebytere
body: @dsanders11 yeah this is purely to aid testing and allow manual running - they can be optional!
created_at: 2025-03-13T21:17:33Z
author_association: MEMBER
path: commits.json
user: login: dsanders11
body: Looks like an accidental inclusion.
created_at: 2025-03-13T21:43:31Z
author_association: MEMBER
path: commits.json
user: login: codebytere
body: oops 
created_at: 2025-03-13T21:45:05Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,83 @@
+name: Check Upstream Sysroot Updates
+
+description: |
+  This workflow runs every two weeks, checks our sysroot scripts against Chromium's
+  at build/linux/sysroot_scripts and opens an issue if there are any new changes.
+
+on:
+  schedule:
+    - cron: "0 0 1,15 * *"
+  workflow_dispatch:
+    inputs:
+      current-sha:
+        type: string
+        description: 'Current SHA for build/linux/sysroot_scripts'
+        required: true
+      upstream-sha:
+        type: string
+        description: 'Upstream SHA for build/linux/sysroot_scripts'
+        required: true
+
+jobs:
+  check-upstream-sysroot:
+    permissions:
+      issues: write
+    runs-on: ubuntu-latest
+    steps:
+    - name: Fetch Current SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.current-sha }}" ]; then
+          CURRENT_SHA="${{ github.event.inputs.current-sha }}"
+        elif [ -f current-sha.json ]; then
+          CURRENT_SHA=$(jq -r '.sha' current-sha.json)
+        else
+          echo "No current SHA provided and current-sha.json not found."
+          exit 1
+        fi
+        echo "CURRENT_SHA=${CURRENT_SHA}" >> $GITHUB_ENV
+    - name: Fetch latest upstream SHA
+      shell: bash
+      run: |
+        if [ -n "${{ github.event.inputs.upstream-sha }}" ]; then
+          UPSTREAM_SHA="${{ github.event.inputs.upstream-sha }}"
+        else
+          UPSTREAM_SHA=$(curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=1" | jq -r '.[0].sha')
+        fi
+        echo "UPSTREAM_SHA=${UPSTREAM_SHA}" >> $GITHUB_ENV
+    - name: Compare current SHA with upstream SHA
+      shell: bash
+      run: |
+        if [ "${{ env.CURRENT_SHA }}" == "${{ env.UPSTREAM_SHA }}" ]; then
+          echo "No changes found - sysroot scripts are up to date!"
+        else
+          curl -s "https://api.github.com/repos/chromium/chromium/commits?path=build/linux/sysroot_scripts&per_page=20" -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" > commits.json
+
+          COMMITS=$(
+            jq -r --arg base_sha "${{ env.CURRENT_SHA }}" '
+              ([.[].sha] | index($base_sha) // length) as $idx |
+              .[0:$idx] | .[] | 
+              "- [`\(.sha[0:7])`](\(.html_url)) \(.commit.message | split("\n")[0])"
+            ' commits.json
+          )
+
+          ISSUE_BODY=$(cat <<EOF
+        ### Upstream sysroot scripts have been updated
+
+        Commits between \`${CURRENT_SHA:0:7}\` and \`${UPSTREAM_SHA:0:7}\`:
+
+        ${COMMITS}
+
+        Please review these changes and update our scripts accordingly.
+        EOF
+          )
+
+          BODY_JSON=$(jq -n --arg body "$ISSUE_BODY" --arg title "Upstream sysroot scripts have changed" '{title: $title, body: $body}')
+
+          curl -X POST \
+            -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
+            -H "Accept: application/vnd.github.v3+json" \
+            -H "Content-Type: application/json" \
+            -d "$BODY_JSON" \
+            "https://api.github.com/repos/${{ github.repository }}/issues"
path: .github/workflows/upstream-sysroot.yml
user: login: dsanders11
body: Unresolving this just because I think we need to use `--body-file=-` vs `--body` here due to the newlines. The linked `e/e` code was forced to do it that way because providing newlines in `--body` seem to get chomped, where as providing the content via `--body-file=-` did not chomp them.
created_at: 2025-03-13T21:45:57Z
author_association: MEMBER

PR comments:
user: login: codebytere
created_at: 2025-03-13T21:36:48Z
body: @dsanders11 
> In this case I'm guessing an issue is desirable because it can be referenced in an associated PR to land the upstream changes?

yes, exactly.

Addressed changes - let me know if i missed anything! As to the Slack event - I suppose we could fire to upgrades? I'm not opposed but also potentially would bias towards @mentioning the team in the issue instead. What do you think?
author_association: MEMBER
user: login: dsanders11
created_at: 2025-03-13T21:52:07Z
body: > As to the Slack event - I suppose we could fire to upgrades? I'm not opposed but also potentially would bias towards @mentioning the team in the issue instead. What do you think?

Historically I feel like there's a lot of noise in our collective GitHub notifications so not sure that would improve visibility too much.

I guess it's just a matter of how priority it is. If it's something that should be done ASAP, I'd opt for firing a Slack message to ensure it gets seen. If it's something that can wait for a while then I think it's fine to do the issue.
author_association: MEMBER
user: login: codebytere
created_at: 2025-03-14T09:12:02Z
body: @dsanders11 I think i'll leave it as an issue and then add a team @mention then - I'd classify it as fairly low-urgency and something that can definitely wait until someone gets to it.
author_association: MEMBER