Skip to content

fix(ci): fix race conditions and syntax errors - #310

Merged
Ryan-Millard merged 8 commits into
mainfrom
fix/ci
Apr 18, 2026
Merged

fix(ci): fix race conditions and syntax errors#310
Ryan-Millard merged 8 commits into
mainfrom
fix/ci

Conversation

@Ryan-Millard

@Ryan-Millard Ryan-Millard commented Apr 18, 2026

Copy link
Copy Markdown
Owner

What was changed & why

The deploy and label workflows failed to run because of syntax errors and omitted inputs - my fault in #308. This fixes that.

Fixes: none

Changes

Just syntax error fixes.

Testing & Verification

N/A - this is a YOLO thing.

Additional Resources

Summary by CodeRabbit

  • Bug Fixes

    • PR automatic labeling now runs as its own step and executes reliably.
  • Chores

    • CI and deployment are gated to wait for the required Docker image before proceeding.
    • Docker builds use additional cache sources to improve build performance.
    • Default base image tag updated from "latest" to "main" for consistency.
  • New Features

    • Added a reusable workflow to poll and wait for Docker image availability with configurable retries and exponential backoff.

@coderabbitai

coderabbitai Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Added a reusable workflow to wait for a Docker image to become available, threaded that check into CI and deploy workflows (including a computed image tag), expanded Docker build cache sources, and fixed an indentation bug so the PR labeler runs as its own step.

Changes

Cohort / File(s) Summary
New wait-for-image workflow & CI/deploy integration
​.github/workflows/wait-for-docker-image.yml, ​.github/workflows/ci.yml, ​.github/workflows/deploy.yml
Added wait-for-docker-image.yml (reusable workflow_call) that polls Docker Hub with exponential backoff. Introduced wait-for-image job and setup job to compute/export an image value; updated CI and deploy jobs to depend on wait-for-image and pass the computed image input (PR-specific tag vs main).
Docker build cache sources
​.github/workflows/docker-ci.yml
Expanded buildx cache-from to include an additional registry cache reference (:buildcache) alongside the existing cache ref (multi-line cache-from).
PR auto-label step fix
​.github/workflows/pr-auto-label.yml
Fixed indentation so actions/labeler runs as a standalone workflow step rather than being nested under the checkout step.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as CI/Deploy Workflow
    participant Waiter as wait-for-docker-image (reusable)
    participant Registry as Docker Hub
    participant Jobs as Dependent Jobs (lint/build/docs/react/deploy)

    Caller->>Waiter: call workflow with `image` input
    Waiter->>Registry: query tag metadata (tags API / docker pull)
    alt image found and fresh
        Registry-->>Waiter: tag_last_pushed >= workflow start
        Waiter-->>Caller: return success
        Caller->>Jobs: proceed with dependent jobs
    else not yet available
        Waiter->>Waiter: sleep, backoff, retry (up to max_attempts)
        opt final fail
            Waiter-->>Caller: exit 1 (fail workflow)
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ci

Poem

I’m a rabbit in the CI glen,
I nibble tags and wait again.
A backoff hop, a patient cheer,
Label fixed — the pipeline’s clear.
Tiny paws, big YAML grin. 🐇✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(ci): fix race conditions and syntax errors' is directly related to the main changeset. The PR addresses syntax errors and introduces a wait-for-image mechanism to fix race conditions in CI/CD workflows, which aligns with the title's promise to fix both issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ci

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/deploy.yml:
- Around line 11-33: The reusable workflow calls (jobs cmake-build,
build-react-app, build-docs) incorrectly use ${{ env.image }} in their with:
inputs which is not available to reusable workflows; replace those references by
either a repository variable (e.g., create a vars entry like IMAGE and use ${{
vars.IMAGE }}) or add a setup job that emits an output (e.g., a setup job that
sets outputs.image) and pass it as ${{ needs.setup.outputs.image }} to the
cmake-build, build-react-app, and build-docs workflow calls; alternatively
inline the literal "ryanmillard/img2num-dev:latest" into each with: image if you
prefer a quick fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 162e7cdc-3fb2-4d50-a9c0-1a105281e05e

📥 Commits

Reviewing files that changed from the base of the PR and between 5e2595a and 7ee4eaf.

📒 Files selected for processing (2)
  • .github/workflows/deploy.yml
  • .github/workflows/pr-auto-label.yml

Comment thread .github/workflows/deploy.yml Outdated
@Ryan-Millard Ryan-Millard changed the title fix(ci): fix omitted image inputs in deploy.yml and indents in pr-auto-label.yml fix(ci): fix race conditions and syntax errors Apr 18, 2026
Repository owner deleted a comment from github-actions Bot Apr 18, 2026
@Ryan-Millard

Ryan-Millard commented Apr 18, 2026

Copy link
Copy Markdown
Owner Author

I just deleted the image and the cache to test the CI on this PR again.

Comment thread .github/workflows/wait-for-docker-image.yml Fixed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
.github/workflows/deploy.yml (1)

24-39: ⚠️ Potential issue | 🔴 Critical

env context is still not allowed in reusable workflow with: inputs — lines 24, 32, and 39 will evaluate to an empty string.

actionlint continues to flag these as errors. GitHub Actions only exposes github, inputs, matrix, needs, strategy, and vars in jobs.<job>.with, so ${{ env.image }} resolves to "" and each called workflow receives an empty image input. This contradicts the PR's stated goal of fixing the deploy workflow.

Replace with either ${{ vars.IMAGE }} (simplest), a setup job that outputs the value, or the literal ryanmillard/img2num-dev:main.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/deploy.yml around lines 24 - 39, The reusable-workflow
inputs are using `${{ env.image }}` which is not available in `jobs.<job>.with`
and therefore passes an empty string; update the `with:` blocks for the
build-react-app and build-docs jobs (the `image:` inputs passed to the reusable
workflows used by the `build-react-app` and `build-docs` jobs) to supply a valid
value — replace `${{ env.image }}` with `${{ vars.IMAGE }}` (preferred), or
alternatively generate the image string in a prior setup job and pass it via
`needs.<job>.outputs.<name>`, or hardcode `ryanmillard/img2num-dev:main` so the
called workflows receive a non-empty `image` input.
🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

13-91: Consider deduplicating the 5× repeated image-tag ternary.

The same github.event_name == 'pull_request' && format(...) || 'ryanmillard/img2num-dev:main' expression is copy-pasted in wait-for-image, lint.container, cmake-build, build-react-app, and build-docs. If the tag scheme ever changes (as it did in this PR, latestmain), all five sites must stay in sync, which is error-prone.

Options:

  • Expose the computed tag as an output of wait-for-image (or a tiny setup job) and reference ${{ needs.wait-for-image.outputs.image }} everywhere. Note: this won't work for lint.container.image directly if container is evaluated before needs, so verify behavior — needs context is allowed under jobs.<job>.container.
  • Define vars.IMAGE_MAIN in repo settings and use ${{ github.event_name == 'pull_request' && format('...:pr-{0}', github.event.pull_request.number) || vars.IMAGE_MAIN }} — still duplicated, but a single source of truth for the base name.

Non-blocking; current form is correct.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 13 - 91, The workflow duplicates the
image selection expression across jobs (wait-for-image, lint.container,
cmake-build, build-react-app, build-docs); consolidate by computing the image
once (e.g., in the wait-for-image job or a dedicated setup job) and exposing it
as an output (reference via needs.wait-for-image.outputs.image) or by defining a
repo/workflow-level var (e.g., vars.IMAGE_MAIN) and using that in a single
conditional expression; update each job’s image/container.image to reference the
computed output/var and remove the repeated ternary to keep a single source of
truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/wait-for-docker-image.yml:
- Around line 49-56: The retry loop incorrectly doubles DELAY before the first
sleep and also sleeps after the final attempt; update the loop that pulls IMAGE
so that initial_delay_seconds (DELAY) is used for the first sleep by moving the
DELAY=$((DELAY * 2)) operation to after the sleep, and avoid sleeping on the
last iteration by only sleeping when the current index i is less than
MAX_ATTEMPTS (i.e., skip sleep when i == MAX_ATTEMPTS); ensure the docker pull
check (docker pull "$IMAGE" && exit 0) remains at the top of the loop so
successful pulls still exit immediately.

---

Duplicate comments:
In @.github/workflows/deploy.yml:
- Around line 24-39: The reusable-workflow inputs are using `${{ env.image }}`
which is not available in `jobs.<job>.with` and therefore passes an empty
string; update the `with:` blocks for the build-react-app and build-docs jobs
(the `image:` inputs passed to the reusable workflows used by the
`build-react-app` and `build-docs` jobs) to supply a valid value — replace `${{
env.image }}` with `${{ vars.IMAGE }}` (preferred), or alternatively generate
the image string in a prior setup job and pass it via
`needs.<job>.outputs.<name>`, or hardcode `ryanmillard/img2num-dev:main` so the
called workflows receive a non-empty `image` input.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 13-91: The workflow duplicates the image selection expression
across jobs (wait-for-image, lint.container, cmake-build, build-react-app,
build-docs); consolidate by computing the image once (e.g., in the
wait-for-image job or a dedicated setup job) and exposing it as an output
(reference via needs.wait-for-image.outputs.image) or by defining a
repo/workflow-level var (e.g., vars.IMAGE_MAIN) and using that in a single
conditional expression; update each job’s image/container.image to reference the
computed output/var and remove the repeated ternary to keep a single source of
truth.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 789707d4-b4ac-4920-8101-3045037ceb04

📥 Commits

Reviewing files that changed from the base of the PR and between 7ee4eaf and 8d440f5.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/deploy.yml
  • .github/workflows/docker-ci.yml
  • .github/workflows/pr-auto-label.yml
  • .github/workflows/wait-for-docker-image.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/pr-auto-label.yml

Comment thread .github/workflows/wait-for-docker-image.yml
* This is smarter and ensures there was a recent Docker Hub push before exiting with a positive result
Repository owner deleted a comment from github-actions Bot Apr 18, 2026
@Ryan-Millard

Copy link
Copy Markdown
Owner Author

I removed the docker image again

@github-actions

Copy link
Copy Markdown
Contributor

🐳 Docker image built successfully!

Image

ryanmillard/img2num-dev:pr-310

Run it locally:

IMG2NUM_IMAGE=ryanmillard/img2num-dev:pr-310 ./img2num sh

@Ryan-Millard

Copy link
Copy Markdown
Owner Author

The cleanup part works on closes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
.github/workflows/deploy.yml (1)

26-29: ⚠️ Potential issue | 🔴 Critical

Use the setup job output through needs, not steps.

These reusable workflow calls run as separate jobs, so steps.set.outputs.image is out of scope here. Since each job already depends on setup, pass ${{ needs.setup.outputs.image }} instead.

🐛 Proposed fix
   cmake-build:
     name: Build WASM
     needs: [wait-for-image, setup]
     uses: ./.github/workflows/cmake-build.yml
     with:
-      image: ${{ steps.set.outputs.image }}
+      image: ${{ needs.setup.outputs.image }}

   build-react-app:
     name: Build React App
     uses: ./.github/workflows/build-react-app.yml
     needs: [cmake-build, wait-for-image, setup]
     with:
       wasm-artifacts-path: packages/js/build-wasm/
-      image: ${{ steps.set.outputs.image }}
+      image: ${{ needs.setup.outputs.image }}

   build-docs:
     name: Build Documentation Site
     needs: [wait-for-image, setup]
     uses: ./.github/workflows/build-docs.yml
     with:
-      image: ${{ steps.set.outputs.image }}
+      image: ${{ needs.setup.outputs.image }}

Verify with:

#!/bin/bash
set -euo pipefail

# Expect no matches after the fix.
rg -nP '\bimage:\s*\$\{\{\s*steps\.set\.outputs\.image\s*\}\}' .github/workflows/deploy.yml || true

# If available, confirm GitHub Actions context validation.
if command -v actionlint >/dev/null 2>&1; then
  actionlint .github/workflows/deploy.yml
fi

Also applies to: 34-37, 41-44

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/deploy.yml around lines 26 - 29, The workflow incorrectly
references a step output (steps.set.outputs.image) which is out of scope for a
reusable workflow job; update the call that uses
./.github/workflows/cmake-build.yml to consume the output from the setup job via
the needs context (replace image: ${{ steps.set.outputs.image }} with image: ${{
needs.setup.outputs.image }}), and apply the same replacement for all other
occurrences (lines referenced around the same block such as the other image:
usages); ensure the job lists setup in needs so needs.setup.outputs.image is
available when invoking the reusable workflow.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @.github/workflows/deploy.yml:
- Around line 26-29: The workflow incorrectly references a step output
(steps.set.outputs.image) which is out of scope for a reusable workflow job;
update the call that uses ./.github/workflows/cmake-build.yml to consume the
output from the setup job via the needs context (replace image: ${{
steps.set.outputs.image }} with image: ${{ needs.setup.outputs.image }}), and
apply the same replacement for all other occurrences (lines referenced around
the same block such as the other image: usages); ensure the job lists setup in
needs so needs.setup.outputs.image is available when invoking the reusable
workflow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7ad8acb8-74d2-4e0c-9440-b71f8706c012

📥 Commits

Reviewing files that changed from the base of the PR and between 8d440f5 and 3596a86.

📒 Files selected for processing (2)
  • .github/workflows/deploy.yml
  • .github/workflows/wait-for-docker-image.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/wait-for-docker-image.yml

@Ryan-Millard
Ryan-Millard merged commit 8ae6ac0 into main Apr 18, 2026
24 of 25 checks passed
@Ryan-Millard
Ryan-Millard deleted the fix/ci branch April 18, 2026 17:12
Ryan-Millard added a commit that referenced this pull request Apr 18, 2026
* fix(ci): fix omitted image inputs in deploy.yml and indents in pr-auto-label.yml
    Previously unable to run as a result of this

* ci(docker-ci): use main's build cache as well in case other build cache doesn't exist

* ci(ci.yml): switch to main from latest docker image tag

* fix(ci): wait for Docker image before running dependent jobs
    This is smarter and ensures there was a recent Docker Hub push before exiting with a positive result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants