Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/actions/wait-for-artifact/action.yml
Copy link
Copy Markdown
Contributor Author

@bitsandfoxes bitsandfoxes May 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We previously relied on this fork https://github.com/vaind/download-artifact (that is in dire need of getting synced), or, like here, we wrap action/download-artifact in 10 lines of bash and call it a day.

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Wait for and download artifact'
description: 'Polls the run''s artifacts API until the named artifact appears, then downloads it.'
inputs:
name:
description: 'Artifact name'
required: true
path:
description: 'Destination path for the artifact contents'
required: false

runs:
using: composite
steps:
- name: Wait for ${{ inputs.name }}
env:
GH_TOKEN: ${{ github.token }}
NAME: ${{ inputs.name }}
shell: pwsh
run: |
for ($i = 0; $i -lt 120; $i++) {
$count = gh api "/repos/$env:GITHUB_REPOSITORY/actions/runs/$env:GITHUB_RUN_ID/artifacts?name=$env:NAME" --jq .total_count
if ([int]$count -gt 0) {
exit 0
Comment on lines +22 to +23
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The PowerShell script in wait-for-artifact will crash if the gh api call fails, as it tries to cast an empty string to an integer without error handling.
Severity: HIGH

Suggested Fix

Wrap the gh api call and subsequent type cast in a try/catch block. In the catch block, handle the error gracefully, for instance by logging a warning and allowing the loop to continue to the next iteration. This will ensure that transient API failures do not crash the entire action and that the polling mechanism can retry as intended.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: .github/actions/wait-for-artifact/action.yml#L22-L23

Potential issue: In the `wait-for-artifact` action, the PowerShell script polls for an
artifact's existence. It executes a `gh api` command and attempts to cast the result to
an integer using `[int]$count`. If the `gh api` command fails for any reason (e.g., a
permission error, a transient network issue, or rate limiting), the output variable
`$count` will be an empty string. The cast `[int]""` then throws a terminating
`InvalidCastException`, which is unhandled and immediately crashes the entire step. This
bypasses the intended 60-minute retry loop, making the action fail instantly on any API
error rather than retrying.

Did we get this right? 👍 / 👎 to inform future reviews.

}
Start-Sleep -Seconds 30
}
Write-Error "Timed out after 60 minutes waiting for artifact: $env:NAME"
exit 1
Comment on lines +18 to +28
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Several jobs and reusable workflows using the wait-for-artifact action are missing the required actions: read permission, which will cause API calls to fail.
Severity: HIGH

Suggested Fix

Add the actions: read permission to the permissions block for all jobs that call the wait-for-artifact action. This includes the test-build-webgl and package-validation jobs in ci.yml, and the jobs in ci.yml that call the reusable test/build workflows.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: .github/actions/wait-for-artifact/action.yml#L14-L28

Potential issue: The custom `wait-for-artifact` action calls a GitHub API endpoint that
requires `actions: read` permission. While this permission was added to the `build.yml`
file and the `build-unity-sdk` job in `ci.yml`, it was not added to other jobs and
reusable workflows that also use this new action. Specifically, the `test-build-webgl`
and `package-validation` jobs in `ci.yml`, as well as the `test-build-android.yml`,
`test-build-linux.yml`, `test-build-windows.yml`, and `test-build-ios.yml` reusable
workflows, are all missing this permission. When these workflows run, the `gh api` call
will fail with a permission denied error, causing the step to fail.

Did we get this right? 👍 / 👎 to inform future reviews.


- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ inputs.name }}
path: ${{ inputs.path }}
30 changes: 13 additions & 17 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ jobs:
name: Build - ${{ inputs.unity-version }}
runs-on: ubuntu-22.04
permissions:
actions: read
checks: write
statuses: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
Comment thread
cursor[bot] marked this conversation as resolved.

- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@f68fdb76e2ea636224182cfb7377ff9a1708f9b8 # v1.3.0
Expand All @@ -48,15 +48,15 @@ jobs:
UNITY_SCRIPT_ARG: unity${{ env.UNITY_VERSION }}

- name: Cache Unity Library
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: samples/unity-of-bugs/Library
key: Library-unity-of-bugs-${{ steps.env.outputs.unityVersion }}-v1
restore-keys: |
Library-unity-of-bugs-${{ steps.env.outputs.unityVersion }}-

- name: Docker Login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # pinned v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ghcr.io
username: ${{ env.GITHUB_ACTOR }}
Expand All @@ -70,7 +70,7 @@ jobs:

- name: Install .NET SDK
if: runner.os != 'Windows'
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
global-json-file: global.json

Expand All @@ -81,32 +81,28 @@ jobs:
run: ./scripts/download-sentry-cli.ps1

- name: Download Android SDK
uses: vaind/download-artifact@e7141b6a94ef28aa3d828b52830cfa1f406a1848 # v4-with-wait-timeout
uses: ./.github/actions/wait-for-artifact
with:
name: Android-sdk
path: package-dev/Plugins/Android
wait-timeout: 3600

- name: Download Cocoa SDK
uses: vaind/download-artifact@e7141b6a94ef28aa3d828b52830cfa1f406a1848 # v4-with-wait-timeout
uses: ./.github/actions/wait-for-artifact
with:
name: Cocoa-sdk
path: package-dev/Plugins
wait-timeout: 3600

- name: Download Linux SDK
uses: vaind/download-artifact@e7141b6a94ef28aa3d828b52830cfa1f406a1848 # v4-with-wait-timeout
uses: ./.github/actions/wait-for-artifact
with:
name: Linux-sdk
path: package-dev/Plugins/Linux
wait-timeout: 3600

- name: Download Windows SDK
uses: vaind/download-artifact@e7141b6a94ef28aa3d828b52830cfa1f406a1848 # v4-with-wait-timeout
uses: ./.github/actions/wait-for-artifact
with:
name: Windows-sdk
path: package-dev/Plugins/Windows
wait-timeout: 3600

- name: Build Sentry.Unity Solution
run: docker exec unity dotnet build -c Release -v:d
Expand All @@ -126,7 +122,7 @@ jobs:
./scripts/pack.ps1

- name: Upload release artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: package-release
if-no-files-found: error
Expand All @@ -140,7 +136,7 @@ jobs:
run: docker exec unity dotnet msbuild /t:UnityEditModeTest /p:Configuration=Release /p:OutDir=other test/Sentry.Unity.Editor.Tests

- name: Publish Test Results
uses: dorny/test-reporter@dc3a92680fcc15842eef52e8c4606ea7ce6bd3f3 # v2.1.1
uses: dorny/test-reporter@a6ddd83ac95ff4586f5d3aceeb314d9a1841db95 # v3.0.0
if: ${{ !cancelled() }}
with:
name: Unity Test Results - ${{ env.UNITY_VERSION }}
Expand All @@ -149,13 +145,13 @@ jobs:
fail-on-error: false

- name: Upload test artifacts (playmode)
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Test results (playmode) - ${{ env.UNITY_VERSION }}
path: artifacts/test/playmode

- name: Upload test artifacts (editmode)
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: Test results (editmode) - ${{ env.UNITY_VERSION }}
path: artifacts/test/editmode
32 changes: 15 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@b173b6ec0100793626c2d9e6b90435061f4fc3e5 # pin@0.11.0
uses: styfle/cancel-workflow-action@d07a454dad7609a92316b57b23c9ccfd4f59af66 # 0.13.1
with:
access_token: ${{ github.token }}

Expand Down Expand Up @@ -53,8 +53,8 @@ jobs:
name: Build Unity SDK
secrets: inherit
permissions:
actions: read
checks: write
statuses: write
contents: read
strategy:
fail-fast: false
Expand All @@ -70,16 +70,15 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.head_ref || github.ref }}
ssh-key: ${{ secrets.CI_DEPLOY_KEY }}

- name: Download UPM package
uses: vaind/download-artifact@e7141b6a94ef28aa3d828b52830cfa1f406a1848 # v4-with-wait-timeout
uses: ./.github/actions/wait-for-artifact
with:
name: package-release
wait-timeout: 3600

- name: Check snapshot
id: snapshot-check
Expand Down Expand Up @@ -136,7 +135,7 @@ jobs:
UNITY_PATH: docker exec unity unity-editor
steps:
- name: Checkout
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@f68fdb76e2ea636224182cfb7377ff9a1708f9b8 # v1.3.0
Expand All @@ -149,7 +148,7 @@ jobs:
swap-storage: true

- name: Docker Login
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # pinned v3
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}
Expand All @@ -166,15 +165,15 @@ jobs:
UNITY_LICENSE_SERVER_CONFIG: ${{ secrets.UNITY_LICENSE_SERVER_CONFIG }}

- name: Download IntegrationTest project
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: test-${{ matrix.unity-version }}

- name: Extract project archive
run: tar -xvzf test-project.tar.gz

- name: Cache Unity Library
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: samples/IntegrationTest/Library
key: Library-IntegrationTest-${{ matrix.platform }}-${{ matrix.unity-version }}-v1
Expand All @@ -184,7 +183,7 @@ jobs:

- name: Restore cached build without Sentry
id: cache-build-nosentry
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: samples/IntegrationTest/Build-NoSentry
key: build-nosentry-${{ matrix.build_platform }}-${{ matrix.unity-version }}
Expand All @@ -196,10 +195,9 @@ jobs:
BUILD_PLATFORM: ${{ matrix.build_platform }}

- name: Download UPM package
uses: vaind/download-artifact@e7141b6a94ef28aa3d828b52830cfa1f406a1848 # v4-with-wait-timeout
uses: ./.github/actions/wait-for-artifact
with:
name: package-release
wait-timeout: 3600

- name: Extract UPM package
run: ./test/Scripts.Integration.Test/extract-package.ps1
Expand All @@ -226,7 +224,7 @@ jobs:
UNITY_VERSION: ${{ matrix.unity-version }}

- name: Upload build size measurement
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: build-size-${{ matrix.platform }}-${{ matrix.unity-version }}
path: build-size-measurements/*.json
Expand All @@ -241,7 +239,7 @@ jobs:
tar -cvzf test-app-webgl.tar.gz samples/IntegrationTest/Build

- name: Upload test app
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: testapp-webgl-compiled-${{ matrix.unity-version }}
if-no-files-found: error
Expand All @@ -250,7 +248,7 @@ jobs:

- name: Upload IntegrationTest project on failure
if: ${{ failure() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: failed-project-${{ matrix.platform }}-${{ matrix.unity-version }}
path: |
Expand Down Expand Up @@ -416,10 +414,10 @@ jobs:
needs: [test-build-webgl, test-build-android, test-compile-ios, test-build-linux, test-build-windows]
steps:
- name: Checkout
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Download all build size measurements
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
pattern: build-size-*
path: build-size-measurements
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/format-code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: recursive

Expand All @@ -22,7 +22,7 @@ jobs:
| xargs clang-format -i -style=file

- name: Install .NET SDK
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
global-json-file: global.json

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ jobs:
steps:
- name: Get auth token
id: token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}

- name: Check out current commit (${{ github.sha }})
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
token: ${{ steps.token.outputs.token }}
fetch-depth: 0
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
runs-on: ${{ inputs.runsOn }}
timeout-minutes: 30
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Select submodules
id: env
Expand Down Expand Up @@ -54,7 +54,7 @@ jobs:
shell: bash

- name: Restore from cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
id: cache
with:
# Note: native SDKs are cached and only built if the respective 'package-dev/Plugins/' directories are empty.
Expand All @@ -78,7 +78,7 @@ jobs:

- name: Install .NET SDK
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
uses: actions/setup-dotnet@d4c94342e560b34958eacfc5d055d21461ed1c5d # v5
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
with:
global-json-file: global.json

Expand All @@ -92,15 +92,15 @@ jobs:

- name: Upload build logs on failure
if: ${{ failure() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
path: |
${{ steps.env.outputs.submodulesPath }}/build.log
modules/sentry-cocoa/*.log
# Lower retention period - we only need this to retry CI.
retention-days: 14

- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ env.TARGET == 'Cocoa' }}
with:
name: ${{ env.TARGET }}-sdk
Expand All @@ -110,7 +110,7 @@ jobs:
# Lower retention period - we only need this to retry CI.
retention-days: 14

- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: ${{ env.TARGET != 'Cocoa' }}
with:
name: ${{ env.TARGET }}-sdk
Expand Down
Loading
Loading