ci(release): pin the actions and keep inputs out of the shell

zizmor flags the HealthChat release workflow now that the rebase PR shows
the whole file as new: five actions referenced by floating major tags, the
workflow_dispatch version input expanded straight into a shell script, and
a Gradle cache on a release build.

- Pin checkout, setup-java, setup-gradle, upload-artifact and
  upload-google-play to commit SHAs with their version in a comment, the
  way every upstream workflow does.
- Pass the version input through the environment instead of expanding it
  into the run script.
- Disable the Gradle cache for the release build so a poisoned cache from
  another workflow cannot reach the signed bundle.
This commit is contained in:
Sedat Qaja
2026-10-19 16:42:35 +02:00
parent b0a577d2b2
commit 2a79103060
@@ -65,7 +65,7 @@ jobs:
# "The operation was canceled" and no other diagnostic. # "The operation was canceled" and no other diagnostic.
runs-on: [self-hosted, Linux, X64] runs-on: [self-hosted, Linux, X64]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
with: with:
fetch-depth: 0 fetch-depth: 0
persist-credentials: false persist-credentials: false
@@ -85,10 +85,13 @@ jobs:
- name: Resolve marketing version - name: Resolve marketing version
id: version id: version
env:
# Passed through the environment, never expanded into the script (zizmor: template-injection).
INPUT_VERSION: ${{ github.event.inputs.version }}
run: | run: |
set -euo pipefail set -euo pipefail
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
VERSION="${{ github.event.inputs.version }}" VERSION="$INPUT_VERSION"
else else
VERSION="${GITHUB_REF_NAME#healthchat-v}" VERSION="${GITHUB_REF_NAME#healthchat-v}"
fi fi
@@ -178,7 +181,7 @@ jobs:
done done
- name: Use JDK 21 - name: Use JDK 21
uses: actions/setup-java@v4 uses: actions/setup-java@cf277c60eb25467037889841efdb72551f06f6c3 # v4.9.1
with: with:
distribution: 'temurin' distribution: 'temurin'
java-version: '21' java-version: '21'
@@ -192,7 +195,10 @@ jobs:
# (SdkConstants.CURRENT_BUILD_TOOLS_VERSION), since nothing sets buildToolsVersion # (SdkConstants.CURRENT_BUILD_TOOLS_VERSION), since nothing sets buildToolsVersion
# here. Both need refreshing in the image when AGP or COMPILE_SDK moves. # here. Both need refreshing in the image when AGP or COMPILE_SDK moves.
- name: Configure gradle - name: Configure gradle
uses: gradle/actions/setup-gradle@v4 uses: gradle/actions/setup-gradle@748248ddd2a24f49513d8f472f81c3a07d4d50e1 # v4.4.4
with:
# Release builds must not consume a cache another workflow could have poisoned.
cache-disabled: true
- name: Decode keystore - name: Decode keystore
run: | run: |
@@ -222,7 +228,7 @@ jobs:
- name: Upload workflow artifacts - name: Upload workflow artifacts
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: healthchat-${{ steps.version.outputs.version }} name: healthchat-${{ steps.version.outputs.version }}
path: | path: |
@@ -232,7 +238,7 @@ jobs:
if-no-files-found: warn if-no-files-found: warn
- name: Upload to Play Store - name: Upload to Play Store
uses: r0adkll/upload-google-play@v1 uses: r0adkll/upload-google-play@e738b9dd8f2476ea806d921b64aacd24f34515a5 # v1.1.5
with: with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
packageName: ch.healthchat.element packageName: ch.healthchat.element