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
44 changes: 44 additions & 0 deletions .github/workflows/image-push.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Image Push
on:
release:
types: [published]
push:
branches: [main]
workflow_dispatch: {}

jobs:
image-push:
runs-on: ubuntu-latest
Comment on lines +10 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add concurrency control to prevent stale latest pushes.

On Line 10, runs are unconstrained; two close pushes to main can race and an older run may finish later and overwrite latest.

Suggested fix
 name: Image Push
+concurrency:
+  group: image-push-${{ github.ref }}
+  cancel-in-progress: true
 on:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
image-push:
runs-on: ubuntu-latest
name: Image Push
concurrency:
group: image-push-${{ github.ref }}
cancel-in-progress: true
on:
...
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/image-push.yaml around lines 10 - 11, The image-push job
can race and overwrite the `latest` tag; add GitHub Actions concurrency to the
job to prevent stale pushes by defining a concurrency group and enabling
cancel-in-progress for the image-push job (use the job name image-push as
reference), e.g., set concurrency.group to a stable identifier per branch or ref
(such as github.ref or github.ref_name) and concurrency.cancel-in-progress to
true so an older run is cancelled when a newer run for the same branch starts.

steps:
- uses: actions/checkout@v4

- name: Determine tags
id: tags
run: |
TAGS="$(git rev-parse --short HEAD)"
if [[ "${{ github.event_name }}" == "push" ]]; then
TAGS="latest ${TAGS}"
fi
if [[ "${{ github.event_name }}" == "release" ]]; then
TAGS="stable ${TAGS} ${{ github.event.release.tag_name }}"
fi
Comment on lines +22 to +24
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Sanitize release tag before using it as an image tag.

On Line 23, ${{ github.event.release.tag_name }} is used directly; release tags may contain invalid container-tag chars (like /), causing build/push failures.

Suggested fix
       - name: Determine tags
         id: tags
         run: |
           TAGS="$(git rev-parse --short HEAD)"
           if [[ "${{ github.event_name }}" == "push" ]]; then
             TAGS="latest ${TAGS}"
           fi
           if [[ "${{ github.event_name }}" == "release" ]]; then
-            TAGS="stable ${TAGS} ${{ github.event.release.tag_name }}"
+            RELEASE_TAG="${{ github.event.release.tag_name }}"
+            SAFE_RELEASE_TAG="$(echo "${RELEASE_TAG}" | tr '/:@ ' '-' | tr -cd '[:alnum:]_.-')"
+            TAGS="stable ${TAGS} ${SAFE_RELEASE_TAG}"
           fi
           echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"
What characters are allowed in OCI/Docker image tags, and is `/` allowed in a tag value?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/image-push.yaml around lines 22 - 24, The workflow
currently appends github.event.release.tag_name directly to TAGS which can
include invalid characters (e.g. '/') for OCI/Docker image tags; compute a
sanitized tag (e.g. CLEAN_TAG) from github.event.release.tag_name by replacing
slashes with hyphens and stripping any characters not in the allowed set
[A-Za-z0-9_.-], then append CLEAN_TAG to TAGS instead of the raw
github.event.release.tag_name; update the block that sets TAGS (the lines
referencing TAGS and github.event.release.tag_name) to use the sanitized
variable.

echo "tags=${TAGS}" >> "$GITHUB_OUTPUT"

- name: Build Forge Image
id: build
uses: redhat-actions/buildah-build@v2
with:
image: forge
context: .
tags: ${{ steps.tags.outputs.tags }}
containerfiles: |
./projects/core/image/Containerfile

- name: Push Forge Image
uses: redhat-actions/push-to-registry@v2
with:
image: ${{ steps.build.outputs.image }}
tags: ${{ steps.build.outputs.tags }}
registry: quay.io/rh_perfscale
username: ${{ secrets.QUAY_USER }}
password: ${{ secrets.QUAY_TOKEN }}
10 changes: 5 additions & 5 deletions projects/core/ci_entrypoint/fournos_resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ def fetch_fournos_job() -> tuple[str, str, dict]:
"""
# Get environment variables
job_name = os.environ.get("FJOB_NAME")
namespace = os.environ.get("FOURNOS_NAMESPACE")
namespace = os.environ.get("FOURNOS_WORKLOAD_NAMESPACE")

if not job_name:
raise ValueError("FJOB_NAME environment variable is required")
if not namespace:
raise ValueError("FOURNOS_NAMESPACE environment variable is required")
raise ValueError("FOURNOS_WORKLOAD_NAMESPACE environment variable is required")

logger.info(f"Fetching FournosJob: {job_name} in namespace: {namespace}")

Expand Down Expand Up @@ -202,8 +202,8 @@ def create_fournos_resolve_command(
)
@click.option(
"--namespace",
help="Namespace for the FournosJob (sets FOURNOS_NAMESPACE if provided)",
envvar="FOURNOS_NAMESPACE",
help="Namespace for the FournosJob (sets FOURNOS_WORKLOAD_NAMESPACE if provided)",
envvar="FOURNOS_WORKLOAD_NAMESPACE",
)
@click.option(
"--dry-run",
Expand All @@ -218,7 +218,7 @@ def fournos_resolve_command(ctx, fjob_name, namespace, dry_run):
if fjob_name:
os.environ["FJOB_NAME"] = fjob_name
if namespace:
os.environ["FOURNOS_NAMESPACE"] = namespace
os.environ["FOURNOS_WORKLOAD_NAMESPACE"] = namespace

# Get vault list from the provided function
try:
Expand Down
2 changes: 1 addition & 1 deletion projects/core/library/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def _update_fjob_export_status(status: dict):
import json

fjob_name = os.environ["FJOB_NAME"]
namespace = os.environ["FOURNOS_NAMESPACE"]
namespace = os.environ["FOURNOS_WORKLOAD_NAMESPACE"]

# Get current fjob status
get_cmd = f"oc get fjob/{fjob_name} -n {namespace} -ojson"
Expand Down
Loading