Skip to content
Merged
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
71 changes: 51 additions & 20 deletions .github/workflows/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ jobs:
# in their own workflow, otherwise GitHub will not issue an OIDC token and
# the Authenticate with GCP step will fail.
permissions:
actions: read # needed by `gh run download` to fetch the env-file artifact
contents: write
id-token: write

Expand Down Expand Up @@ -145,29 +144,61 @@ jobs:
# Secret Manager secrets (Cloud Run), so one image serves all environments.
# The image itself only contains the repo's committed .env (common vars).
# download-artifact@v4 resolves the artifact through the run-scoped Artifacts
# v4 API. On ephemeral ARC pods the results service is occasionally not yet
# consistent for the run when the pod starts, returning a transient 404 that
# the action would surface as a hard miss. That would make this step "fail"
# and, via the outcome gate below, silently deploy WITHOUT the env secrets.
# Retry the download so a transient 404 doesn't get mistaken for "no artifact".
# A genuinely absent artifact (caller has no prepare-env job) still exhausts
# the loop and leaves outcome != success, which the gates below tolerate.
- name: Download .env artifact
# v4 API (authenticated by the injected runtime token, so no `actions:`
# permission is needed). On ephemeral ARC pods the results service is
# occasionally not yet consistent for the run when the pod starts, returning
# a transient 404. Without a retry that 404 is mistaken for "no artifact" and,
# via the outcome gate below, the service deploys WITHOUT its env secrets.
# Re-run the action a few times with a gap; each attempt is continue-on-error.
# The final `env_artifact` step (whose outcome the gates below key on) then
# succeeds iff a .env was actually downloaded, so a genuinely absent artifact
# still leaves outcome != success and the gates skip cleanly as before.
- name: Download .env artifact (attempt 1)
id: dl1
if: ${{ inputs.deploy_type != 'release-only' }}
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: env-file
path: ${{ runner.temp }}/env-file

- name: Wait before .env retry 2
if: ${{ inputs.deploy_type != 'release-only' && steps.dl1.outcome == 'failure' }}
run: sleep 15
- name: Download .env artifact (attempt 2)
id: dl2
if: ${{ inputs.deploy_type != 'release-only' && steps.dl1.outcome == 'failure' }}
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: env-file
path: ${{ runner.temp }}/env-file

- name: Wait before .env retry 3
if: ${{ inputs.deploy_type != 'release-only' && steps.dl1.outcome == 'failure' && steps.dl2.outcome == 'failure' }}
run: sleep 30
- name: Download .env artifact (attempt 3)
id: dl3
if: ${{ inputs.deploy_type != 'release-only' && steps.dl1.outcome == 'failure' && steps.dl2.outcome == 'failure' }}
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: env-file
path: ${{ runner.temp }}/env-file
Comment on lines +180 to +187

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Unused step id on final download attempt

id: dl3 is declared on the third download attempt but never referenced downstream — the env_artifact step uses a find check rather than inspecting steps.dl3.outcome. The id has no effect and can be dropped to reduce noise, though it is harmless as-is.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!


# Single, stable signal the downstream gates key on: success iff a .env was
# actually downloaded by any attempt above. A genuinely absent artifact
# leaves this at 'failure' (continue-on-error keeps the deploy going).
- name: Resolve env-file download outcome
id: env_artifact
if: ${{ inputs.deploy_type != 'release-only' }}
continue-on-error: true
env:
GH_TOKEN: ${{ github.token }}
run: |
for i in 1 2 3 4 5; do
if gh run download "${{ github.run_id }}" -n env-file -D "${{ runner.temp }}/env-file"; then
echo "Downloaded env-file on attempt $i"
exit 0
fi
echo "env-file download attempt $i failed (transient 404 or artifact absent), retrying in 15s..."
sleep 15
done
echo "env-file artifact not downloadable after 5 attempts; deploy will proceed without attached env secrets"
if find "${{ runner.temp }}/env-file" -name '.env' -type f | grep -q .; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Suppressing stderr from find keeps the log clean when all download attempts fail and the directory was never created — the existing logic (grep -q . exits 1, then exit 1) is already correct, but without redirection the No such file or directory message appears in CI output alongside the intentional "env-file not downloaded" message.

Suggested change
if find "${{ runner.temp }}/env-file" -name '.env' -type f | grep -q .; then
if find "${{ runner.temp }}/env-file" -name '.env' -type f 2>/dev/null | grep -q .; then

echo "env-file present"
exit 0
fi
echo "env-file not downloaded after 3 attempts; deploy will proceed without attached env secrets"
exit 1

- name: Build Docker image
Expand Down
55 changes: 36 additions & 19 deletions .github/workflows/integration-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ jobs:
runs-on: ${{ inputs.runner != '' && inputs.runner || 'arc-shared-dev' }}
environment: development
permissions:
actions: read # needed by `gh run download` to fetch the env-file artifact
contents: read
id-token: write
pull-requests: write
Expand All @@ -131,24 +130,42 @@ jobs:
uses: actions/checkout@v3

# download-artifact@v4 resolves the artifact through the run-scoped Artifacts
# v4 API. On ephemeral ARC pods the results service is occasionally not yet
# consistent for the run when the pod starts, returning a *non-retryable*
# "404 workflow run not found". That window closes within seconds, so retry
# the download instead of failing the whole job on the first miss.
- name: Download .env artifact
env:
GH_TOKEN: ${{ github.token }}
run: |
for i in 1 2 3 4 5; do
if gh run download "${{ github.run_id }}" -n env-file -D .; then
echo "Downloaded env-file on attempt $i"
exit 0
fi
echo "env-file download attempt $i failed (artifact backend not consistent yet), retrying in 15s..."
sleep 15
done
echo "env-file artifact never became downloadable after 5 attempts"
exit 1
# v4 API (authenticated by the injected runtime token, so no `actions:`
# permission is needed). On ephemeral ARC pods the results service is
# occasionally not yet consistent for the run when the pod starts, returning
# a *non-retryable* "404 workflow run not found" that fails the whole job.
# The window closes within seconds, so re-run the action a few times with a
# gap. Each attempt is continue-on-error and gated on the previous outcome;
# the final attempt is not, so genuine failures still fail the job.
- name: Download .env artifact (attempt 1)
id: dl1
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: env-file
path: .

- name: Wait before .env retry 2
if: ${{ steps.dl1.outcome == 'failure' }}
run: sleep 15
- name: Download .env artifact (attempt 2)
id: dl2
if: ${{ steps.dl1.outcome == 'failure' }}
continue-on-error: true
uses: actions/download-artifact@v4
with:
name: env-file
path: .

- name: Wait before .env retry 3
if: ${{ steps.dl1.outcome == 'failure' && steps.dl2.outcome == 'failure' }}
run: sleep 30
- name: Download .env artifact (attempt 3, final)
if: ${{ steps.dl1.outcome == 'failure' && steps.dl2.outcome == 'failure' }}
uses: actions/download-artifact@v4
with:
name: env-file
path: .

- name: Load environment variables from .env
run: |
Expand Down
Loading