Skip to content

Commit 561f4aa

Browse files
authored
fix: optimize adhoc artifact uploads with identifiers (#22)
* fix: optimize adhoc artifact uploads and naming * fix: rename custom-ref to custom-identifier, add validation
1 parent fa2f267 commit 561f4aa

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,33 @@ jobs:
6969
| `keystore-path` | where the keystore should be placed | No | `release.keystore` |
7070
| `rock-build-extra-params` | Extra parameters for rock build:android | No | - |
7171
| `comment-bot` | Whether to comment PR with build link | No | `true` |
72-
| `custom-ref` | Custom app reference for artifact naming | No | - |
72+
| `custom-identifier` | Custom identifier used in artifact naming for re-sign and ad-hoc flows to distinguish builds with the same native fingerprint | No | - |
73+
74+
## Artifact Naming
75+
76+
The action uses two distinct naming strategies for uploads:
77+
78+
### ZIP Artifacts (native build caching)
79+
80+
ZIP artifacts store the native build for reuse. The naming depends on the flow:
81+
82+
- **Ad-hoc flow** (`ad-hoc: true`): ZIP name uses **fingerprint only**`rock-android-{variant}-{fingerprint}`. One ZIP per fingerprint, shared across all builds with the same native code. Skipped if already uploaded.
83+
- **Non-ad-hoc re-sign flow** (e.g. `pull_request` with `re-sign: true`): ZIP name includes an **identifier**`rock-android-{variant}-{identifier}-{fingerprint}`. Used as the distribution mechanism without adhoc builds.
84+
- **Regular builds** (no `re-sign`): ZIP name uses **fingerprint only** `rock-android-{variant}-{fingerprint}`
85+
86+
### Ad-Hoc Artifacts (distribution to testers)
87+
88+
When `ad-hoc: true`, distribution files (APK + `index.html`) are uploaded under a name that **always includes an identifier**: `rock-android-{variant}-{identifier}-{fingerprint}`. This ensures every uploaded adhoc build can point to unique distribution URL based on `{identifier}`, even when multiple builds share the same native fingerprint.
89+
90+
### Identifier Priority
91+
92+
The identifier distinguishes builds that share the same native fingerprint (e.g., concurrent builds from different branches).
93+
It is resolved in this order:
94+
1. `custom-identifier` input — explicit value provided by the caller (e.g., commit SHA of the head of the PR branch)
95+
2. PR number — automatically extracted from `pull_request` events
96+
3. Short commit SHA — 7-character fallback for push events and dispatches
97+
98+
> **Note:** The identifier becomes part of artifact names and S3 paths. Allowed characters: `a-z`, `A-Z`, `0-9`, `-`, `.`, `_`. Commas are used internally as trait delimiters and converted to hyphens (e.g., `debug,42``debug-42`), so they must not appear in the identifier. Spaces, slashes, and shell metacharacters are also not allowed.
7399
74100
## Outputs
75101

action.yml

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ inputs:
6868
description: 'Whether to send a comment under PR with the link to the generated build'
6969
required: false
7070
default: true
71-
custom-ref:
72-
description: 'Custom app reference for artifact naming'
71+
custom-identifier:
72+
description: 'Custom identifier used in artifact naming for re-sign and ad-hoc flows to distinguish builds with the same native fingerprint'
7373
required: false
7474

7575
outputs:
@@ -290,16 +290,28 @@ runs:
290290
shell: bash
291291
working-directory: ${{ inputs.working-directory }}
292292

293-
- name: Update Artifact Name for re-signed builds
294-
if: ${{ env.ARTIFACT_URL && inputs.re-sign == 'true' }}
293+
- name: Set Identifier
294+
if: ${{ inputs.re-sign == 'true' || inputs.ad-hoc == 'true' }}
295295
run: |
296-
if [ "${{ github.event_name }}" = "pull_request" ]; then
296+
if [ -n "${{ inputs.custom-identifier }}" ]; then
297+
IDENTIFIER="${{ inputs.custom-identifier }}"
298+
if ! echo "$IDENTIFIER" | grep -qE '^[a-zA-Z0-9._-]+$'; then
299+
echo "Invalid 'custom-identifier': '$IDENTIFIER'. Use only alphanumeric characters, hyphens, dots, and underscores."
300+
exit 1
301+
fi
302+
elif [ "${{ github.event_name }}" = "pull_request" ]; then
297303
IDENTIFIER="${{ github.event.pull_request.number }}"
298-
elif [ -n "${{ inputs.custom-ref }}" ]; then
299-
IDENTIFIER="${{ inputs.custom-ref }}"
300304
else
301305
IDENTIFIER=$(echo "$GITHUB_SHA" | cut -c1-7)
302306
fi
307+
echo "IDENTIFIER=$IDENTIFIER" >> $GITHUB_ENV
308+
shell: bash
309+
310+
# Non-ad-hoc re-sign flow: add identifier to ARTIFACT_NAME so the re-signed ZIP Artifact doesn't overwrite the base ZIP.
311+
# Skipped for ad-hoc — ARTIFACT_NAME stays fingerprint-only (one ZIP Artifact per fingerprint).
312+
- name: Update Artifact Name for re-signed builds
313+
if: ${{ env.ARTIFACT_URL && inputs.re-sign == 'true' && inputs.ad-hoc != 'true' }}
314+
run: |
303315
ARTIFACT_TRAITS="${{ inputs.variant }},${IDENTIFIER}"
304316
ARTIFACT_TRAITS_HYPHENATED=$(echo "$ARTIFACT_TRAITS" | tr ',' '-')
305317
ARTIFACT_TRAITS_HYPHENATED_FINGERPRINT="${ARTIFACT_TRAITS_HYPHENATED}-${FINGERPRINT}"
@@ -328,28 +340,45 @@ runs:
328340
path: ${{ env.ARTIFACT_PATH }}
329341
if-no-files-found: error
330342

343+
# Non-ad-hoc re-sign flow: upload ZIP Artifact with {identifier}-{fingerprint} name
331344
# For re-signed builds, the ARTIFACT_NAME may contain PR-number, while Rock will save the artifact without PR trait in its cache.
332345
# We need to upload the artifact with the PR-number in the name, that's why we use --binary-path with appropriate ARTIFACT_PATH that accounts for it.
333-
- name: Upload Artifact to Remote Cache for re-signed builds
334-
if: ${{ env.PROVIDER_NAME != 'GitHub' && inputs.re-sign == 'true' }}
346+
- name: Upload re-signed ZIP Artifact for non-ad-hoc flow
347+
if: ${{ env.PROVIDER_NAME != 'GitHub' && inputs.re-sign == 'true' && inputs.ad-hoc != 'true' }}
335348
run: |
336349
OUTPUT=$(npx rock remote-cache upload --name ${{ env.ARTIFACT_NAME }} --binary-path "${{ env.ARTIFACT_PATH }}" --json --verbose) || (echo "$OUTPUT" && exit 1)
337350
echo "ARTIFACT_URL=$(echo "$OUTPUT" | jq -r '.url')" >> $GITHUB_ENV
338351
shell: bash
339352

340-
- name: Upload Artifact to Remote Cache for regular builds
341-
if: ${{ env.PROVIDER_NAME != 'GitHub' && inputs.re-sign != 'true' && !env.ARTIFACT_URL }}
353+
# Upload ZIP Artifact with {fingerprint}-only name as base ZIP Artifact for caching only (first build only).
354+
# Runs only when no cached artifact exists (!ARTIFACT_URL), meaning native build was done from scratch.
355+
# Excludes non-ad-hoc re-sign, which uploads with identifier in the name.
356+
# Applies to:
357+
# - regular builds (no ad-hoc, no re-sign)
358+
# - re-sign with ad-hoc
359+
- name: Upload ZIP Artifact for caching
360+
if: ${{ env.PROVIDER_NAME != 'GitHub' && !env.ARTIFACT_URL && (inputs.re-sign != 'true' || inputs.ad-hoc == 'true') }}
342361
run: |
343362
OUTPUT=$(npx rock remote-cache upload --name ${{ env.ARTIFACT_NAME }} --json --verbose) || (echo "$OUTPUT" && exit 1)
344363
echo "ARTIFACT_URL=$(echo "$OUTPUT" | jq -r '.url')" >> $GITHUB_ENV
345364
shell: bash
346365

347-
# For ad-hoc builds, the ARTIFACT_NAME may contain PR-number, while Rock will save the artifact without PR trait in its cache.
348-
# We need to upload the artifact with the PR-number in the name, that's why we use --binary-path with appropriate ARTIFACT_PATH that accounts for it.
366+
367+
# Ad-hoc uploads always include an identifier in the name {identifier}-{fingerprint}
368+
- name: Set Ad-Hoc Artifact Name
369+
if: ${{ inputs.ad-hoc == 'true' }}
370+
run: |
371+
ADHOC_TRAITS="${{ inputs.variant }},${IDENTIFIER}"
372+
ADHOC_TRAITS_HYPHENATED=$(echo "$ADHOC_TRAITS" | tr ',' '-')
373+
echo "ADHOC_ARTIFACT_NAME=rock-android-${ADHOC_TRAITS_HYPHENATED}-${FINGERPRINT}" >> $GITHUB_ENV
374+
shell: bash
375+
376+
# Uploads APK/AAB + index.html under ad-hoc/{ADHOC_ARTIFACT_NAME}/.
377+
# The ARTIFACT_URL output points to index.html
349378
- name: Upload for Ad-hoc distribution
350379
if: ${{ env.PROVIDER_NAME != 'GitHub' && inputs.ad-hoc == 'true' }}
351380
run: |
352-
OUTPUT=$(npx rock remote-cache upload --name ${{ env.ARTIFACT_NAME }} --binary-path "${{ env.ARTIFACT_PATH }}" --json --ad-hoc) || (echo "$OUTPUT" && exit 1)
381+
OUTPUT=$(npx rock remote-cache upload --name ${{ env.ADHOC_ARTIFACT_NAME }} --binary-path "${{ env.ARTIFACT_PATH }}" --json --ad-hoc) || (echo "$OUTPUT" && exit 1)
353382
echo "ARTIFACT_URL=$(echo "$OUTPUT" | jq -r '.url')" >> $GITHUB_ENV
354383
shell: bash
355384

0 commit comments

Comments
 (0)