Skip to content

CORE-1345 Support reusing image when there is no application changes#136

Open
tundeaoni wants to merge 2 commits intomainfrom
CORE-1345-support-skipping-image-build-and-testing-when-only-nomad-or-nomad-pack-change-made-docker-build
Open

CORE-1345 Support reusing image when there is no application changes#136
tundeaoni wants to merge 2 commits intomainfrom
CORE-1345-support-skipping-image-build-and-testing-when-only-nomad-or-nomad-pack-change-made-docker-build

Conversation

@tundeaoni
Copy link
Contributor

@tundeaoni tundeaoni commented Oct 31, 2025

@tundeaoni tundeaoni requested a review from a team as a code owner October 31, 2025 18:18
@remerge-hal
Copy link

This comment ensures that the correct Slack channel is notified after the team/project label CORE has been added to this pull request.

See this comment for details.

run: |
#!/usr/bin/env bash
set -euo pipefail
EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ env.DEFAULT_BUILD_EXCLUDES }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

General approach:
Set the value of DEFAULT_BUILD_EXCLUDES as an environment variable using the env: block in the workflow step, and reference it in the shell script using shell variable syntax ($DEFAULT_BUILD_EXCLUDES), not via ${{ ... }} interpolation. This prevents code injection via workflow-level interpolation and utilizes the shell's built-in variable substitution.

Detailed fix:

  • In the step with id: compute_hash, move the assignment of ${{ env.DEFAULT_BUILD_EXCLUDES }} out of the shell script and into the step’s env: section:
    • Add DEFAULT_BUILD_EXCLUDES: ${{ env.DEFAULT_BUILD_EXCLUDES }} under the env: key.
  • In the shell script, use EXCLUDES="$DEFAULT_BUILD_EXCLUDES" instead of referencing the variable with ${{ ... }}.
  • No changes to imports or method definitions are needed; this is a straightforward YAML modification and does not alter the workflow's logic.

Files/lines to change:

  • .github/workflows/docker.yml:
    • Add env: to the - name: Compute hash and check if image exists step (ID compute_hash) with a line to set DEFAULT_BUILD_EXCLUDES from ${{ env.DEFAULT_BUILD_EXCLUDES }}.
    • Change the line EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}" to EXCLUDES="$DEFAULT_BUILD_EXCLUDES".

Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -260,10 +260,12 @@
 
       - name: Compute hash and check if image exists
         id: compute_hash
+        env:
+          DEFAULT_BUILD_EXCLUDES: ${{ env.DEFAULT_BUILD_EXCLUDES }}
         run: |
           #!/usr/bin/env bash
           set -euo pipefail
-          EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
+          EXCLUDES="$DEFAULT_BUILD_EXCLUDES"
           if [ -n "${{ inputs.build-excludes }}" ]; then
             EXCLUDES+=",${{ inputs.build-excludes }}"
           fi
EOF
@@ -260,10 +260,12 @@

- name: Compute hash and check if image exists
id: compute_hash
env:
DEFAULT_BUILD_EXCLUDES: ${{ env.DEFAULT_BUILD_EXCLUDES }}
run: |
#!/usr/bin/env bash
set -euo pipefail
EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
EXCLUDES="$DEFAULT_BUILD_EXCLUDES"
if [ -n "${{ inputs.build-excludes }}" ]; then
EXCLUDES+=",${{ inputs.build-excludes }}"
fi
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
#!/usr/bin/env bash
set -euo pipefail
EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
if [ -n "${{ inputs.build-excludes }}" ]; then

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.build-excludes }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

To fix the potential code injection flaw, one should avoid using ${{ inputs.build-excludes }} directly inside the script block. Instead, pass the input value into an environment variable using the env: block of the step, and reference it using shell-native variable expansion ($BUILD_EXCLUDES). Specifically, in the step running the shell script (id: compute_hash), add an env entry: BUILD_EXCLUDES: ${{ inputs.build-excludes }}. Then, throughout the shell script, replace ${{ inputs.build-excludes }} with $BUILD_EXCLUDES. The same should be done for other workflow inputs being used in the shell script, if they are also user-controlled and interpolated directly.

Changes needed:

  • In the step with id: compute_hash, add to the env section: BUILD_EXCLUDES: ${{ inputs.build-excludes }} (or, create the env block if not present).
  • Replace every instance of ${{ inputs.build-excludes }} in the run script of that step with $BUILD_EXCLUDES.

No additional dependencies or imports are needed.


Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -260,12 +260,14 @@
 
       - name: Compute hash and check if image exists
         id: compute_hash
+        env:
+          BUILD_EXCLUDES: ${{ inputs.build-excludes }}
         run: |
           #!/usr/bin/env bash
           set -euo pipefail
           EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
-          if [ -n "${{ inputs.build-excludes }}" ]; then
-            EXCLUDES+=",${{ inputs.build-excludes }}"
+          if [ -n "$BUILD_EXCLUDES" ]; then
+            EXCLUDES+=",$BUILD_EXCLUDES"
           fi
 
           if [ -n "${{ inputs.tag }}" ]; then
EOF
@@ -260,12 +260,14 @@

- name: Compute hash and check if image exists
id: compute_hash
env:
BUILD_EXCLUDES: ${{ inputs.build-excludes }}
run: |
#!/usr/bin/env bash
set -euo pipefail
EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
if [ -n "${{ inputs.build-excludes }}" ]; then
EXCLUDES+=",${{ inputs.build-excludes }}"
if [ -n "$BUILD_EXCLUDES" ]; then
EXCLUDES+=",$BUILD_EXCLUDES"
fi

if [ -n "${{ inputs.tag }}" ]; then
Copilot is powered by AI and may make mistakes. Always verify output.
set -euo pipefail
EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
if [ -n "${{ inputs.build-excludes }}" ]; then
EXCLUDES+=",${{ inputs.build-excludes }}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.build-excludes }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

To fix the issue, assign the potentially untrusted input (${{ inputs.build-excludes }}) to an environment variable using the env: key in the GitHub Actions workflow step, rather than interpolating it directly in the run: script. Then, inside the shell script, reference the variable using bash's native $BUILD_EXCLUDES instead of ${{ ... }}. This approach prevents GitHub Actions' expression evaluation from inadvertently exposing the shell to code injection risks, as shell variable expansion does not enable command substitution from workflow input.

Specifically, modify the "Compute hash and check if image exists" step (lines 262–317 in the provided snippet):

  • Update the step to add an env: section, setting something like BUILD_EXCLUDES: ${{ inputs.build-excludes }}.
  • Change line if [ -n "${{ inputs.build-excludes }}" ]; then to use [ -n "$BUILD_EXCLUDES" ]
  • And where the value is appended (EXCLUDES+=",${{ inputs.build-excludes }}"), switch to EXCLUDES+=",${BUILD_EXCLUDES}".

No new methods or imports are needed; this is pure YAML and shell quoting discipline.


Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -260,12 +260,14 @@
 
       - name: Compute hash and check if image exists
         id: compute_hash
+        env:
+          BUILD_EXCLUDES: ${{ inputs.build-excludes }}
         run: |
           #!/usr/bin/env bash
           set -euo pipefail
           EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
-          if [ -n "${{ inputs.build-excludes }}" ]; then
-            EXCLUDES+=",${{ inputs.build-excludes }}"
+          if [ -n "$BUILD_EXCLUDES" ]; then
+            EXCLUDES+=",${BUILD_EXCLUDES}"
           fi
 
           if [ -n "${{ inputs.tag }}" ]; then
@@ -313,7 +311,6 @@
           # Print for debugging
           echo "IMAGE=${IMAGE}"
           echo "EXISTS=${EXISTS}"
-
       - name: Print results
         run: |
           echo "Computed tag: ${{ env.image }}"
EOF
@@ -260,12 +260,14 @@

- name: Compute hash and check if image exists
id: compute_hash
env:
BUILD_EXCLUDES: ${{ inputs.build-excludes }}
run: |
#!/usr/bin/env bash
set -euo pipefail
EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
if [ -n "${{ inputs.build-excludes }}" ]; then
EXCLUDES+=",${{ inputs.build-excludes }}"
if [ -n "$BUILD_EXCLUDES" ]; then
EXCLUDES+=",${BUILD_EXCLUDES}"
fi

if [ -n "${{ inputs.tag }}" ]; then
@@ -313,7 +311,6 @@
# Print for debugging
echo "IMAGE=${IMAGE}"
echo "EXISTS=${EXISTS}"

- name: Print results
run: |
echo "Computed tag: ${{ env.image }}"
Copilot is powered by AI and may make mistakes. Always verify output.
EXCLUDES+=",${{ inputs.build-excludes }}"
fi

if [ -n "${{ inputs.tag }}" ]; then

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.tag }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

General fix:
The best way to mitigate this sort of code injection in GitHub Actions shell scripts is to place the untrusted expression (${{ inputs.tag }}) into an intermediate environment variable via the env: block and then only reference it in the shell script using the native variable syntax ($TAG). This ensures that the untrusted input cannot break out of its variable assignment, as GitHub Actions handles safe quoting for environment variables automatically.

Detailed steps:

  • Find where ${{ inputs.tag }} is present in the shell script in the run: block (lines 271, 273, 274, 292).
  • At the step level, define a new environment variable, such as TAG_INPUT: ${{ inputs.tag }}.
  • In the shell script, reference the value as $TAG_INPUT rather than interpolating directly with ${{ inputs.tag }}.
  • Where the script assigns TAG="${{ inputs.tag }}", instead assign TAG="$TAG_INPUT".
  • Likewise, update lines where IMAGE and similar variables were composed with ${{ inputs.tag }} to use $TAG_INPUT or $TAG as appropriate.
  • Do not reference ${{ inputs.tag }} directly in shell code.

Imports/Definitions needed:
No imports necessary. No new packages are needed.


Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -260,6 +260,8 @@
 
       - name: Compute hash and check if image exists
         id: compute_hash
+        env:
+          TAG_INPUT: ${{ inputs.tag }}
         run: |
           #!/usr/bin/env bash
           set -euo pipefail
@@ -268,10 +270,10 @@
             EXCLUDES+=",${{ inputs.build-excludes }}"
           fi
 
-          if [ -n "${{ inputs.tag }}" ]; then
-            echo "🔖 Tag '${{ inputs.tag }}' provided — skipping hash computation."
-            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${{ inputs.tag }}"
-            TAG="${{ inputs.tag }}"
+          if [ -n "$TAG_INPUT" ]; then
+            echo "🔖 Tag '$TAG_INPUT' provided — skipping hash computation."
+            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:$TAG_INPUT"
+            TAG="$TAG_INPUT"
             EXISTS="false" # Assume not built yet — can still be checked later if desired
           else
             # Enable extended globbing and recursive globs (**)
EOF
@@ -260,6 +260,8 @@

- name: Compute hash and check if image exists
id: compute_hash
env:
TAG_INPUT: ${{ inputs.tag }}
run: |
#!/usr/bin/env bash
set -euo pipefail
@@ -268,10 +270,10 @@
EXCLUDES+=",${{ inputs.build-excludes }}"
fi

if [ -n "${{ inputs.tag }}" ]; then
echo "🔖 Tag '${{ inputs.tag }}' provided — skipping hash computation."
IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${{ inputs.tag }}"
TAG="${{ inputs.tag }}"
if [ -n "$TAG_INPUT" ]; then
echo "🔖 Tag '$TAG_INPUT' provided — skipping hash computation."
IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:$TAG_INPUT"
TAG="$TAG_INPUT"
EXISTS="false" # Assume not built yet — can still be checked later if desired
else
# Enable extended globbing and recursive globs (**)
Copilot is powered by AI and may make mistakes. Always verify output.
fi

if [ -n "${{ inputs.tag }}" ]; then
echo "🔖 Tag '${{ inputs.tag }}' provided — skipping hash computation."

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.tag }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

To fix this code injection risk, do not interpolate ${{ inputs.tag }} directly in the shell script. Instead, assign it as an environment variable, and then refer to it in the script via the shell-native $TAG syntax.
Specifically:

  • In the affected step (Compute hash and check if image exists), add an env: section to pass inputs.tag into the script as an environment variable (e.g., TAG_INPUT: ${{ inputs.tag }}), or, if you want to preserve the original variable name, as TAG: ${{ inputs.tag }}.
  • In the script, refer to it using $TAG (not ${{ inputs.tag }}).
  • Apply the same pattern for other input variables if you use user-supplied input elsewhere in the shell code.

This approach ensures that user data is not implicitly interpreted by the shell, thus preventing code injection.


Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -260,6 +260,8 @@
 
       - name: Compute hash and check if image exists
         id: compute_hash
+        env:
+          TAG: ${{ inputs.tag }}
         run: |
           #!/usr/bin/env bash
           set -euo pipefail
@@ -268,10 +270,10 @@
             EXCLUDES+=",${{ inputs.build-excludes }}"
           fi
 
-          if [ -n "${{ inputs.tag }}" ]; then
-            echo "🔖 Tag '${{ inputs.tag }}' provided — skipping hash computation."
-            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${{ inputs.tag }}"
-            TAG="${{ inputs.tag }}"
+          if [ -n "$TAG" ]; then
+            echo "🔖 Tag '$TAG' provided — skipping hash computation."
+            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:$TAG"
+            TAG="$TAG"
             EXISTS="false" # Assume not built yet — can still be checked later if desired
           else
             # Enable extended globbing and recursive globs (**)
EOF
@@ -260,6 +260,8 @@

- name: Compute hash and check if image exists
id: compute_hash
env:
TAG: ${{ inputs.tag }}
run: |
#!/usr/bin/env bash
set -euo pipefail
@@ -268,10 +270,10 @@
EXCLUDES+=",${{ inputs.build-excludes }}"
fi

if [ -n "${{ inputs.tag }}" ]; then
echo "🔖 Tag '${{ inputs.tag }}' provided — skipping hash computation."
IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${{ inputs.tag }}"
TAG="${{ inputs.tag }}"
if [ -n "$TAG" ]; then
echo "🔖 Tag '$TAG' provided — skipping hash computation."
IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:$TAG"
TAG="$TAG"
EXISTS="false" # Assume not built yet — can still be checked later if desired
else
# Enable extended globbing and recursive globs (**)
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
# Compute deterministic content-based hash
TAG=$("${FIND_CMD[@]}" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)

IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${TAG}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.project }
, which may be controlled by an external user.
# Compute deterministic content-based hash
TAG=$("${FIND_CMD[@]}" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)

IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${TAG}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ env.REPOSITORY }
, which may be controlled by an external user.
Potential code injection in
${ env.REPOSITORY }
, which may be controlled by an external user.
Potential code injection in
${ env.REPOSITORY }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

The safest and most robust fix is to avoid injecting untrusted input with ${{ ... }} syntax inside any shell commands, as this can enable code injection.
Instead, use environment variables for all untrusted inputs:

  • In the YAML step, place the untrusted input value into an environment variable via the env: key.
  • Inside the shell script, use shell native syntax ($REPOSITORY) for variable expansion, not ${{ env.REPOSITORY }}.
  • Update line 292 in the workflow, replacing ${{ env.REPOSITORY }} with $REPOSITORY.

To implement:

  • In .github/workflows/docker.yml, edit line 292 so that the shell assignment to IMAGE uses $REPOSITORY instead of ${{ env.REPOSITORY }}.
  • No new imports, just edit inside the shell script block.

Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -289,7 +289,7 @@
             # Compute deterministic content-based hash
             TAG=$("${FIND_CMD[@]}" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
 
-            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${TAG}"
+            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${REPOSITORY}/${{ inputs.image }}:${TAG}"
 
             # Check if image exists in registry
             if docker manifest inspect "$IMAGE" >/dev/null 2>&1; then
EOF
@@ -289,7 +289,7 @@
# Compute deterministic content-based hash
TAG=$("${FIND_CMD[@]}" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)

IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${TAG}"
IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${REPOSITORY}/${{ inputs.image }}:${TAG}"

# Check if image exists in registry
if docker manifest inspect "$IMAGE" >/dev/null 2>&1; then
Copilot is powered by AI and may make mistakes. Always verify output.
# Compute deterministic content-based hash
TAG=$("${FIND_CMD[@]}" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)

IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${TAG}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ inputs.image }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

To fix this code injection vulnerability, the workflow should avoid injecting untrusted input directly into shell commands or variables using the ${{ ... }} expression. Instead, set the value to an environment variable in the env: section, and expand that environment variable using shell-native syntax ("$IMAGE" rather than "${{ inputs.image }}").

In detail:

  • Set each external/untrusted input (specifically, registry, project, image, and tag) to environment variables in the env: block of the corresponding shell step.
  • Use the environment variable references in shell ($IMAGE, $REGISTRY, $PROJECT, $TAG) rather than the ${{ ... }} expressions within the run script.
  • Refactor lines where their values are currently being interpolated using ${{ ... }} to use these environment variables.
  • This change should occur for all interpolations of those inputs within the script (not just line 292).
  • No imports are needed—this is pure GitHub Actions YAML/shell.

Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -260,18 +260,24 @@
 
       - name: Compute hash and check if image exists
         id: compute_hash
+        env:
+          REGISTRY: ${{ inputs.registry }}
+          PROJECT: ${{ inputs.project }}
+          IMAGE: ${{ inputs.image }}
+          TAG_INPUT: ${{ inputs.tag }}
+          BUILD_EXCLUDES: ${{ inputs.build-excludes }}
         run: |
           #!/usr/bin/env bash
           set -euo pipefail
           EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
-          if [ -n "${{ inputs.build-excludes }}" ]; then
-            EXCLUDES+=",${{ inputs.build-excludes }}"
+          if [ -n "$BUILD_EXCLUDES" ]; then
+            EXCLUDES+=",${BUILD_EXCLUDES}"
           fi
 
-          if [ -n "${{ inputs.tag }}" ]; then
-            echo "🔖 Tag '${{ inputs.tag }}' provided — skipping hash computation."
-            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${{ inputs.tag }}"
-            TAG="${{ inputs.tag }}"
+          if [ -n "$TAG_INPUT" ]; then
+            echo "🔖 Tag '$TAG_INPUT' provided — skipping hash computation."
+            IMAGE_PATH="$REGISTRY/$PROJECT/${{ env.REPOSITORY }}/$IMAGE:$TAG_INPUT"
+            TAG="$TAG_INPUT"
             EXISTS="false" # Assume not built yet — can still be checked later if desired
           else
             # Enable extended globbing and recursive globs (**)
@@ -289,29 +289,29 @@
             # Compute deterministic content-based hash
             TAG=$("${FIND_CMD[@]}" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)
 
-            IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${TAG}"
+            IMAGE_PATH="$REGISTRY/$PROJECT/${{ env.REPOSITORY }}/$IMAGE:$TAG"
 
             # Check if image exists in registry
-            if docker manifest inspect "$IMAGE" >/dev/null 2>&1; then
-              echo "✅ Image $IMAGE already exists - skipping build"
+            if docker manifest inspect "$IMAGE_PATH" >/dev/null 2>&1; then
+              echo "✅ Image $IMAGE_PATH already exists - skipping build"
               EXISTS="true"
             else
-              echo "🚀 Image $IMAGE not found — proceed to build"
+              echo "🚀 Image $IMAGE_PATH not found — proceed to build"
               EXISTS="false"
             fi
           fi
 
           # Export values for GitHub Actions
           {
-            echo "image=${IMAGE}"
+            echo "image=${IMAGE_PATH}"
             echo "image_exists=${EXISTS}"
             echo "tag=${TAG}"
           } >> "$GITHUB_ENV"
 
-          echo "image=${IMAGE}" >> "$GITHUB_OUTPUT"
+          echo "image=${IMAGE_PATH}" >> "$GITHUB_OUTPUT"
 
           # Print for debugging
-          echo "IMAGE=${IMAGE}"
+          echo "IMAGE=${IMAGE_PATH}"
           echo "EXISTS=${EXISTS}"
 
       - name: Print results
EOF
@@ -260,18 +260,24 @@

- name: Compute hash and check if image exists
id: compute_hash
env:
REGISTRY: ${{ inputs.registry }}
PROJECT: ${{ inputs.project }}
IMAGE: ${{ inputs.image }}
TAG_INPUT: ${{ inputs.tag }}
BUILD_EXCLUDES: ${{ inputs.build-excludes }}
run: |
#!/usr/bin/env bash
set -euo pipefail
EXCLUDES="${{ env.DEFAULT_BUILD_EXCLUDES }}"
if [ -n "${{ inputs.build-excludes }}" ]; then
EXCLUDES+=",${{ inputs.build-excludes }}"
if [ -n "$BUILD_EXCLUDES" ]; then
EXCLUDES+=",${BUILD_EXCLUDES}"
fi

if [ -n "${{ inputs.tag }}" ]; then
echo "🔖 Tag '${{ inputs.tag }}' provided — skipping hash computation."
IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${{ inputs.tag }}"
TAG="${{ inputs.tag }}"
if [ -n "$TAG_INPUT" ]; then
echo "🔖 Tag '$TAG_INPUT' provided — skipping hash computation."
IMAGE_PATH="$REGISTRY/$PROJECT/${{ env.REPOSITORY }}/$IMAGE:$TAG_INPUT"
TAG="$TAG_INPUT"
EXISTS="false" # Assume not built yet — can still be checked later if desired
else
# Enable extended globbing and recursive globs (**)
@@ -289,29 +289,29 @@
# Compute deterministic content-based hash
TAG=$("${FIND_CMD[@]}" -exec sha256sum {} \; | sort | sha256sum | cut -d' ' -f1)

IMAGE="${{ inputs.registry }}/${{ inputs.project }}/${{ env.REPOSITORY }}/${{ inputs.image }}:${TAG}"
IMAGE_PATH="$REGISTRY/$PROJECT/${{ env.REPOSITORY }}/$IMAGE:$TAG"

# Check if image exists in registry
if docker manifest inspect "$IMAGE" >/dev/null 2>&1; then
echo "✅ Image $IMAGE already exists - skipping build"
if docker manifest inspect "$IMAGE_PATH" >/dev/null 2>&1; then
echo "✅ Image $IMAGE_PATH already exists - skipping build"
EXISTS="true"
else
echo "🚀 Image $IMAGE not found — proceed to build"
echo "🚀 Image $IMAGE_PATH not found — proceed to build"
EXISTS="false"
fi
fi

# Export values for GitHub Actions
{
echo "image=${IMAGE}"
echo "image=${IMAGE_PATH}"
echo "image_exists=${EXISTS}"
echo "tag=${TAG}"
} >> "$GITHUB_ENV"

echo "image=${IMAGE}" >> "$GITHUB_OUTPUT"
echo "image=${IMAGE_PATH}" >> "$GITHUB_OUTPUT"

# Print for debugging
echo "IMAGE=${IMAGE}"
echo "IMAGE=${IMAGE_PATH}"
echo "EXISTS=${EXISTS}"

- name: Print results
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated

- name: Print results
run: |
echo "Computed tag: ${{ env.image }}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ env.image }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

To fix the potential code injection vulnerability, we should assign the value to an environment variable using the env: property of the step, and then reference that variable in the shell using the proper shell syntax ("$image"), not via GitHub Actions expression syntax. In this case, for the 'Print results' step, we will move ${{ env.image }} and ${{ env.image_exists }} into environment variables (e.g., IMAGE and IMAGE_EXISTS) using the env: key, and inside the shell script, reference them as "$IMAGE" and "$IMAGE_EXISTS". This prevents shell injection even if those values contain special characters.

Only the 'Print results' step (lines 317–321) needs updates: add an env: mapping, and change the script to use shell variables instead of ${{ env. ... }}.


Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -315,9 +315,12 @@
           echo "EXISTS=${EXISTS}"
 
       - name: Print results
+        env:
+          IMAGE: ${{ env.image }}
+          IMAGE_EXISTS: ${{ env.image_exists }}
         run: |
-          echo "Computed tag: ${{ env.image }}"
-          echo "Image exists: ${{ env.image_exists }}"
+          echo "Computed tag: $IMAGE"
+          echo "Image exists: $IMAGE_EXISTS"
 
       - name: Extract metadata (tags, labels) for Docker
         id: meta
EOF
@@ -315,9 +315,12 @@
echo "EXISTS=${EXISTS}"

- name: Print results
env:
IMAGE: ${{ env.image }}
IMAGE_EXISTS: ${{ env.image_exists }}
run: |
echo "Computed tag: ${{ env.image }}"
echo "Image exists: ${{ env.image_exists }}"
echo "Computed tag: $IMAGE"
echo "Image exists: $IMAGE_EXISTS"

- name: Extract metadata (tags, labels) for Docker
id: meta
Copilot is powered by AI and may make mistakes. Always verify output.
- name: Print results
run: |
echo "Computed tag: ${{ env.image }}"
echo "Image exists: ${{ env.image_exists }}"

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ env.image_exists }
, which may be controlled by an external user.

Copilot Autofix

AI 3 months ago

To fix the code injection risk, the variable ${{ env.image_exists }} should not be interpolated directly using expression syntax in the run: block. Instead, pass the value as an environment variable and then reference it via shell-native variable expansion (i.e., $image_exists). Specifically, in the .github/workflows/docker.yml file, modify the relevant step ("Print results") to set an environment variable, then use the shell's $image_exists syntax when echoing the value. No behavioral change is introduced; the fix simply ensures that any injected meta-characters cannot be interpreted by the shell.


Suggested changeset 1
.github/workflows/docker.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -315,9 +315,11 @@
           echo "EXISTS=${EXISTS}"
 
       - name: Print results
+        env:
+          IMAGE_EXISTS: ${{ env.image_exists }}
         run: |
           echo "Computed tag: ${{ env.image }}"
-          echo "Image exists: ${{ env.image_exists }}"
+          echo "Image exists: $IMAGE_EXISTS"
 
       - name: Extract metadata (tags, labels) for Docker
         id: meta
EOF
@@ -315,9 +315,11 @@
echo "EXISTS=${EXISTS}"

- name: Print results
env:
IMAGE_EXISTS: ${{ env.image_exists }}
run: |
echo "Computed tag: ${{ env.image }}"
echo "Image exists: ${{ env.image_exists }}"
echo "Image exists: $IMAGE_EXISTS"

- name: Extract metadata (tags, labels) for Docker
id: meta
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants