diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1f7b112..c8b9ea23 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,9 @@ env: SERIOUS_PYTHON_SITE_PACKAGES: "${{ github.workspace }}/site-packages" UV_PYTHON: "3.12" +permissions: + contents: read + jobs: macos: name: Test on macOS (Python ${{ matrix.python_version }}) @@ -27,10 +30,12 @@ jobs: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Setup Flutter - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + uses: kuhnroyal/flutter-fvm-config-action/setup@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 with: path: '.fvmrc' cache: true @@ -52,17 +57,19 @@ jobs: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Setup Flutter - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + uses: kuhnroyal/flutter-fvm-config-action/setup@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 with: path: '.fvmrc' cache: true - name: Setup iOS Simulator id: simulator - uses: futureware-tech/simulator-action@v4 + uses: futureware-tech/simulator-action@e89aa8f93d3aec35083ff49d2854d07f7186f7f5 # v5 with: # https://github.com/futureware-tech/simulator-action/wiki/Devices-macos-latest model: 'iPhone 16 Pro Max' @@ -73,9 +80,11 @@ jobs: - name: Run tests working-directory: "src/serious_python/example/flet_example" + env: + SIMULATOR_UDID: ${{ steps.simulator.outputs.udid }} run: | dart run serious_python:main package app/src --platform iOS --python-version ${{ matrix.python_version }} --requirements flet==0.28.3 - flutter test integration_test --device-id ${{ steps.simulator.outputs.udid }} --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} + flutter test integration_test --device-id ${SIMULATOR_UDID} --dart-define=EXPECTED_PYTHON_VERSION=${{ matrix.python_version }} android: name: Test on Android (Python ${{ matrix.python_version }}) @@ -88,10 +97,12 @@ jobs: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Setup Flutter - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + uses: kuhnroyal/flutter-fvm-config-action/setup@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 with: path: '.fvmrc' cache: true @@ -103,19 +114,24 @@ jobs: sudo udevadm trigger --name-match=kvm - name: Gradle cache - uses: gradle/actions/setup-gradle@v3 + uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0 + with: + # Disable the Gradle cache on tag/release builds to avoid cache poisoning. + cache-disabled: ${{ startsWith(github.ref, 'refs/tags/') }} - name: AVD cache - uses: actions/cache@v4 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 id: avd-cache with: path: | ~/.android/avd/* ~/.android/adb* key: avd + # Disable cache restore on tag/release builds to avoid cache poisoning. + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Setup Android Emulator + Run tests - uses: reactivecircus/android-emulator-runner@v2 + uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0 env: EMULATOR_PORT: 5554 with: @@ -147,10 +163,12 @@ jobs: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Setup Flutter - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + uses: kuhnroyal/flutter-fvm-config-action/setup@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 with: path: '.fvmrc' cache: true @@ -180,19 +198,24 @@ jobs: SERIOUS_PYTHON_VERSION: ${{ matrix.python_version }} steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Setup uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + # Disable the uv cache on tag/release builds to avoid cache poisoning. + enable-cache: ${{ !startsWith(github.ref, 'refs/tags/') }} - name: Get Flutter version from ".fvmrc" - uses: kuhnroyal/flutter-fvm-config-action/config@v3 + uses: kuhnroyal/flutter-fvm-config-action/config@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 id: fvm-config-action with: path: '.fvmrc' - name: Setup Flutter - uses: subosito/flutter-action@v2 + uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2.23.0 with: flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }} channel: ${{ matrix.arch == 'arm64' && 'master' || 'stable' }} # https://github.com/subosito/flutter-action/issues/345#issuecomment-2657332687 @@ -249,15 +272,19 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 + persist-credentials: false - name: Setup uv - uses: astral-sh/setup-uv@v6 + uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 + with: + # Disable the uv cache on tag/release builds to avoid cache poisoning. + enable-cache: ${{ !startsWith(github.ref, 'refs/tags/') }} - name: Setup Flutter - uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + uses: kuhnroyal/flutter-fvm-config-action/setup@c378498f1d1962d33039c3989411093ef8a17b2c # v3.3 with: path: '.fvmrc' cache: true @@ -321,4 +348,4 @@ jobs: publish_pkg src/serious_python_windows publish_pkg src/serious_python_linux sleep 600 - publish_pkg src/serious_python \ No newline at end of file + publish_pkg src/serious_python diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 00000000..e9ba32c0 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,28 @@ +name: zizmor - GitHub Actions Security Analysis + +on: + push: + pull_request: + +permissions: {} + +jobs: + zizmor: + name: Run zizmor + runs-on: ubuntu-latest + permissions: + security-events: write + contents: read + steps: + - name: Checkout + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - name: Run zizmor + uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 + with: + # Fork PRs get a read-only token (no security-events: write), so the + # SARIF upload would fail. Skip it for forks — they still get inline + # annotations; pushes and same-repo PRs upload to code scanning. + advanced-security: ${{ github.event.pull_request.head.repo.fork != true }}