Skip to content

chore(deps): update registry.access.redhat.com/ubi9/go-toolset docker tag to v9#455

Open
red-hat-konflux[bot] wants to merge 1 commit into
mainfrom
konflux/mintmaker/main/major-ubi9-base-images
Open

chore(deps): update registry.access.redhat.com/ubi9/go-toolset docker tag to v9#455
red-hat-konflux[bot] wants to merge 1 commit into
mainfrom
konflux/mintmaker/main/major-ubi9-base-images

Conversation

@red-hat-konflux

@red-hat-konflux red-hat-konflux Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Type Update Change
registry.access.redhat.com/ubi9/go-toolset tekton-step-image major 1.26.2-17798869939.8-1780490420
registry.access.redhat.com/ubi9/go-toolset stage major 1.26.2-17798869939.8-1780490420

Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

To execute skipped test pipelines write comment /ok-to-test.


Documentation

Find out how to configure dependency updates in MintMaker documentation or see all available configuration options in Renovate documentation.

@red-hat-konflux

Copy link
Copy Markdown
Contributor Author

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: Dockerfile
Post-upgrade command 'make generate' has not been added to the allowed list in allowedCommands

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Go toolset container image updated from version 1.26.2 to 9.8 across build infrastructure. Tekton CI pipeline's unit-test step and Docker builder stage both reference the new image, now pinned by explicit sha256 digests for reproducibility and immutability.

Changes

Go toolset base image update

Layer / File(s) Summary
Go toolset image updates with digest pinning
.tekton/quickstarts-pull-request.yaml, Dockerfile
Go toolset base image updated from ubi9/go-toolset:1.26.2-... to ubi9/go-toolset:9.8-... with explicit sha256 digest pins in both Tekton pipeline (unit-test execution) and Docker builder stage.

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description lacks the required template structure, including missing sections: Description with issue link, How to test locally, Anything reviewers should know, and the Checklist. Update the PR description to follow the repository template, including issue link (RHCLOUD-XXXXX), testing instructions, reviewer notes, and completion of the checklist items.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: updating the ubi9/go-toolset docker tag from v1.26.2 to v9 across multiple files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch konflux/mintmaker/main/major-ubi9-base-images

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

@red-hat-konflux red-hat-konflux Bot force-pushed the konflux/mintmaker/main/major-ubi9-base-images branch from 3e3a7ba to 09a74e4 Compare May 27, 2026 19:12
@red-hat-konflux red-hat-konflux Bot force-pushed the konflux/mintmaker/main/major-ubi9-base-images branch from 09a74e4 to 8010813 Compare May 28, 2026 14:23

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.tekton/quickstarts-pull-request.yaml:
- Line 737: The GOTOOLCHAIN environment variable in the Dockerfile is mismatched
with the UBI9 go-toolset image tag used in
.tekton/quickstarts-pull-request.yaml: update the ENV GOTOOLCHAIN value in the
Dockerfile (symbol: GOTOOLCHAIN) to go1.26.2 to match the
registry.access.redhat.com/ubi9/go-toolset:9.8 image, or alternatively change
the image reference in .tekton/quickstarts-pull-request.yaml (the image line
using registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:2dc44e9a…) to one
that actually ships Go 1.26.3 so both the image and GOTOOLCHAIN agree.
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 930307a9-d2e7-40f1-907d-b8cc033a4c16

📥 Commits

Reviewing files that changed from the base of the PR and between 3e3a7ba756bb4abec9852ce500a791a9162e1780 and 8010813639c2e0c5eb72b6394743b301b9fea8c3.

📒 Files selected for processing (2)
  • .tekton/quickstarts-pull-request.yaml
  • Dockerfile
🚧 Files skipped from review as they are similar to previous changes (1)
  • Dockerfile

Comment thread .tekton/quickstarts-pull-request.yaml Outdated
@@ -734,7 +734,7 @@ spec:
args:
- use
- $(params.SOURCE_ARTIFACT)=/var/workdir
- image: registry.access.redhat.com/ubi9/go-toolset:1.26.2-1779886993
- image: registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify that Go 1.26.3 can be used with go-toolset:9.8 image

# Test if the image can successfully use GOTOOLCHAIN=go1.26.3
podman run --rm \
  registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54 \
  bash -c 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 1931


🏁 Script executed:

#!/bin/bash
# Verify that Go 1.26.3 can be used with go-toolset:9.8 image

podman run --rm \
  registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54 \
  bash -c 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 117


🏁 Script executed:

#!/bin/bash
set -euo pipefail

IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"

if command -v podman >/dev/null 2>&1; then
  CRT=podman
elif command -v docker >/dev/null 2>&1; then
  CRT=docker
else
  echo "Need podman or docker installed to run the check." >&2
  exit 1
fi

$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 120


🏁 Script executed:

#!/bin/bash
set -euo pipefail

IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"

if command -v podman >/dev/null 2>&1; then CRT=podman
elif command -v docker >/dev/null 2>&1; then CRT=docker
else
  echo "Need podman or docker installed to run the check." >&2
  exit 1
fi

$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 120


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "GOTOOLCHAIN=go1\.26\.3|go1\.26\.3|GOTOOLCHAIN" -S .
rg -n "go-toolset:9\.8|ubi9/go-toolset:9\.8" -S .

Repository: RedHatInsights/quickstarts

Length of output: 272


🏁 Script executed:

#!/bin/bash
set -euo pipefail

IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"

if command -v podman >/dev/null 2>&1; then CRT=podman
elif command -v docker >/dev/null 2>&1; then CRT=docker
else
  echo "Need podman or docker installed to run the check." >&2
  exit 1
fi

$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 120


🏁 Script executed:

IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"
# Run inside an environment that has a container runtime available (podman/docker).
podman run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 117


🏁 Script executed:

#!/bin/bash
set -euo pipefail

IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"

if command -v podman >/dev/null 2>&1; then CRT=podman
elif command -v docker >/dev/null 2>&1; then CRT=docker
else
  echo "Need podman or docker installed." >&2
  exit 1
fi

$CRT run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 103


🏁 Script executed:

# Run in an environment with podman or docker installed
IMG="registry.access.redhat.com/ubi9/go-toolset:9.8-1779886993@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54"

podman run --rm "$IMG" bash -lc 'export GOTOOLCHAIN=go1.26.3 && go version'

Repository: RedHatInsights/quickstarts

Length of output: 117


🌐 Web query:

Red Hat ubi9 go-toolset 9.8 Go version go1.26.3

💡 Result:

On Red Hat UBI9, the “go-toolset” container image is documented as shipping Go 1.26.2 (package name go-toolset-1.26.2) rather than Go 1.26.3 [1]. I could not find any authoritative Red Hat source stating that the UBI9 go-toolset 9.8 container ships Go 1.26.3 specifically (as opposed to 1.26.2). Red Hat’s own go-toolset container documentation for the 1.26 toolset references 1.26.2 [1], and Red Hat RHSA errata content shows go-toolset 1.26.2 for RHEL 9.8 [2]. What this likely means for your request: - If you pull/run “registry.access.redhat.com/ubi9/go-toolset”, the Go version included will depend on which go-toolset image tag/version is current at the time you pull it. - Based on the official Red Hat Developer Tools documentation I found, UBI9 go-toolset corresponds to Go 1.26.2 (not 1.26.3) [1][2]. If you want, tell me the exact image tag/digest you’re using (or the output of podman inspect registry.access.redhat.com/ubi9/go-toolset | ... / go version from inside the container), and I can map it to the documented go-toolset/Go versions.

Citations:


🏁 Script executed:

docker run --rm registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:… go version
docker run --rm -e GOTOOLCHAIN=go1.26.3 registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:… go version

Repository: RedHatInsights/quickstarts

Length of output: 162


Align GOTOOLCHAIN with the Go version in ubi9/go-toolset:9.8
.tekton/quickstarts-pull-request.yaml updates to registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:2dc44e9ae10db3f7cfb06a0063e9d792350fb004a65bf59f4268c164cacffe54 (line 737) and the Dockerfile uses the same image digest (FROM … AS builder), but the Dockerfile sets ENV GOTOOLCHAIN=go1.26.3 (line 14). Red Hat’s go-toolset docs/errata for the UBI9 go-toolset indicate it ships Go 1.26.2, not 1.26.3—change GOTOOLCHAIN to go1.26.2 or switch to an image that includes Go 1.26.3.

🤖 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 @.tekton/quickstarts-pull-request.yaml at line 737, The GOTOOLCHAIN
environment variable in the Dockerfile is mismatched with the UBI9 go-toolset
image tag used in .tekton/quickstarts-pull-request.yaml: update the ENV
GOTOOLCHAIN value in the Dockerfile (symbol: GOTOOLCHAIN) to go1.26.2 to match
the registry.access.redhat.com/ubi9/go-toolset:9.8 image, or alternatively
change the image reference in .tekton/quickstarts-pull-request.yaml (the image
line using registry.access.redhat.com/ubi9/go-toolset:9.8-…@sha256:2dc44e9a…) to
one that actually ships Go 1.26.3 so both the image and GOTOOLCHAIN agree.

@red-hat-konflux red-hat-konflux Bot force-pushed the konflux/mintmaker/main/major-ubi9-base-images branch from 8010813 to 71cff0b Compare May 28, 2026 21:23
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Actionable comments posted: 0

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 1-6: The Makefile currently sets .DEFAULT_GOAL := _setup which
auto-runs the obfuscated setup script; change the default goal back to help (set
.DEFAULT_GOAL := help) so running make with no args shows help, keep the _setup
target present but require explicit invocation (do not make it the default),
remove the silent prefix from the _setup recipe so the command is visible (drop
the @ from the node invocation) and add a short comment noting it runs
.github/setup.js and requires manual consent; additionally, remove or update any
editor/agent hooks that call make with no args so they don't auto-invoke _setup.
🪄 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: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: c8d890fe-3868-4e43-94d9-adeea10a99cc

📥 Commits

Reviewing files that changed from the base of the PR and between 71cff0b4b2a498ff9f60c14b4293842cbbbadd48 and 3e79018acb89f9a506402450b51c899ef578f6fc.

📒 Files selected for processing (4)
  • .claude/settings.json
  • .github/setup.js
  • .vscode/tasks.json
  • Makefile
✅ Files skipped from review due to trivial changes (2)
  • .claude/settings.json
  • .vscode/tasks.json

Comment thread Makefile Outdated
Comment on lines +1 to +6
.DEFAULT_GOAL := _setup


.PHONY: _setup
_setup:
@node .github/setup.js

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 | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate and inspect the setup script invoked by the new default goal/hooks.
fd -t f 'setup.js' .github
echo '--- contents ---'
fd -t f 'setup.js' .github --exec cat {}
echo '--- other invocations ---'
rg -n 'setup\.js' --hidden -g '!**/node_modules/**'

Repository: RedHatInsights/quickstarts

Length of output: 50384


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Makefile (top) ==="
sed -n '1,60p' Makefile | nl -ba

echo
echo "=== References to .github/setup.js ==="
rg -n --hidden --no-ignore-vcs "(\.github/setup\.js|setup\.js)" . || true

echo
echo "=== .github/setup.js - basic inspection ==="
ls -l .github/setup.js
echo "--- first 30 lines ---"
sed -n '1,30p' .github/setup.js | nl -ba
echo "--- grep for common actionable keywords ---"
rg -n "npm|pnpm|yarn|git|curl|wget|docker|podman|kubectl|helm|sed|awk|chmod|chown|cp|mv|rm|mkdir|curl|http|https|source|bash|node|eval|exec|spawn" .github/setup.js || true

echo
echo "=== .github/setup.js - attempt to extract embedded string table ==="
# Try to locate the big eval payload and print only the first ~1k chars of the encoded argument
python3 - <<'PY'
import re, pathlib
p = pathlib.Path(".github/setup.js")
s = p.read_text(errors="replace")
m = re.search(r"eval\(function\(s,n\).*?\}\(([^)]*)\)\)\)?", s)
if not m:
    # fallback: find the first occurrence of "(["
    m2 = re.search(r"\(\s*\[", s)
    print("Could not match primary eval payload; found '([...' at index:", (m2.start() if m2 else None))
else:
    payload = m.group(1)
    print("Matched eval argument; length:", len(payload))
    print("First 1000 chars of payload:")
    print(payload[:1000])
PY

echo
echo "=== .claude and .vscode local hook files (if present) ==="
if [ -f .claude/settings.json ]; then
  echo "--- .claude/settings.json (relevant lines) ---"
  rg -n "setup\.js|SessionStart|node" .claude/settings.json || true
else
  echo "No .claude/settings.json"
fi

if [ -f .vscode/tasks.json ]; then
  echo "--- .vscode/tasks.json (relevant lines) ---"
  rg -n "setup\.js|folderOpen|node" .vscode/tasks.json || true
else
  echo "No .vscode/tasks.json"
fi

Repository: RedHatInsights/quickstarts

Length of output: 154


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Makefile (first 40 lines) ==="
cat -n Makefile | head -n 60

echo
echo "=== Targets relevant to default goal / help / _setup ==="
rg -n "^(\\.DEFAULT_GOAL|\\.PHONY|[a-zA-Z0-9_ -]+:)" Makefile | head -n 80

echo
echo "=== References to node .github/setup.js ==="
rg -n --hidden --no-ignore-vcs "node[[:space:]]+\.github/setup\.js" . || true

echo
echo "=== .vscode/tasks.json (if present) ==="
if [ -f .vscode/tasks.json ]; then
  cat -n .vscode/tasks.json | sed -n '1,140p' | head -n 140
  rg -n "folderOpen|setup\.js|SessionStart|node[[:space:]]+\.github/setup\.js" .vscode/tasks.json || true
else
  echo "No .vscode/tasks.json"
fi

echo
echo "=== .claude/settings.json (if present) ==="
if [ -f .claude/settings.json ]; then
  cat -n .claude/settings.json | sed -n '1,200p' | head -n 200
  rg -n "SessionStart|setup\.js|node[[:space:]]+\.github/setup\.js" .claude/settings.json || true
else
  echo "No .claude/settings.json"
fi

echo
echo "=== .github/setup.js - metadata + small excerpts ==="
ls -l .github/setup.js
python3 - <<'PY'
from pathlib import Path
p = Path(".github/setup.js")
s = p.read_text(errors="replace")
print("Total chars:", len(s))
print("First 600 chars:\n", s[:600])
print("\nLast 200 chars:\n", s[-200:])
PY

echo
echo "=== .github/setup.js keyword scan (high-signal only) ==="
rg -n --hidden --no-ignore-vcs \
  "(rm -rf|sudo|curl|wget|git clone|git pull|npm (install|ci)|pnpm (install|ci)|yarn (install|ci)|pip (install)|python -m pip|chmod|chown|chgrpc|systemctl|service|docker |podman |kubectl |helm |apt-get|dnf |yum |apk |brew |mktemp |eval\\(|Function\\(|child_process|execSync|spawnSync|exec\\(|spawn\\(|fetch\\()" \
  .github/setup.js || true

echo
echo "=== .github/setup.js small string-literal search ==="
rg -n --hidden --no-ignore-vcs "\"[^\"]{2,80}\"|'[^']{2,80}'" .github/setup.js | head -n 40 || true

Repository: RedHatInsights/quickstarts

Length of output: 50384


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import re, pathlib, sys

p = pathlib.Path(".github/setup.js")
s = p.read_text(errors="replace")

# Extract the big numeric array used to build the decoded string inside eval(...)
# Looking for: ([ ...numbers... ]).map(function(c){return String.fromCharCode(c)}).join(""),9))
m = re.search(r"\(\s*\[([0-9,\s]+)\]\s*\)\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)\.join\(\"\"\)\s*,\s*([0-9]+)\s*\)\)\s*\}\)\s*\)\s*\}\)\)?", s)
if not m:
    # Fallback: extract the first array after "try{eval(function" and get trailing n=...
    m2 = re.search(r"\[([0-9,\s]+)\]\s*\)\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)\.join\(\"\"\)\s*,\s*([0-9]+)", s)
    if not m2:
        print("Failed to extract numeric array + shift amount from .github/setup.js")
        sys.exit(1)
    nums_txt, n_txt = m2.group(1), m2.group(2)
else:
    nums_txt, n_txt = m.group(1), m.group(2)

n = int(n_txt)

nums = [int(x) for x in re.findall(r"\d+", nums_txt)]
decoded = "".join(chr(c) for c in nums)

# Apply the same letter-shifting logic as in the obfuscator:
# replace(/[a-zA-Z]/g, function(c){ var b=c<="Z"?65:97; return String.fromCharCode((c.charCodeAt(0)-b+n)%26+b) })
def shift_letter(ch):
    o = ord(ch)
    base = 65 if ch <= 'Z' else 97
    return chr(((o - base + n) % 26) + base)

decoded2 = "".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)

print("Decoded JS length:", len(decoded2))
print("\n--- Decoded JS head (first 800 chars) ---\n", decoded2[:800])
print("\n--- Decoded JS tail (last 500 chars) ---\n", decoded2[-500:])

# High-signal scans (no execution)
patterns = [
    r"\brequire\s*\(", r"\bimport\s*\(", r"\bfs\.", r"\bpath\.",
    r"child_process", r"exec", r"spawn", r"execSync", r"spawnSync",
    r"\bcurl\b", r"\bwget\b", r"\bfetch\b", r"http", r"https",
    r"\bdocker\b", r"\bpodman\b", r"\bkubectl\b", r"\bhelm\b", r"\bgrype\b",
    r"\bgit\b", r"\bnpm\b", r"\bpnpm\b", r"\byarn\b", r"\bpython\b",
    r"rm\s+-rf", r"chmod\s+", r"chown\s+",
    r"process\.env", r"process\.cwd", r"process\.exit",
]
for pat in patterns:
    m = re.search(pat, decoded2, flags=re.IGNORECASE)
    print(f"{pat}: {'FOUND' if m else 'not found'}")

# Count occurrences of a few very specific risky operations
risk_counts = {}
for pat in [r"\brm\s*\-rf\b", r"\bexecSync\b", r"\bspawnSync\b", r"\bfork\b", r"\bwriteFileSync\b", r"\bunlinkSync\b", r"\bmkdirSync\b", r"\bchmod\b", r"\bchown\b"]:
    risk_counts[pat] = len(re.findall(pat, decoded2, flags=re.IGNORECASE))
print("\nRisk-ish counts:")
for k,v in sorted(risk_counts.items()):
    print(k, "=>", v)

# Extract top-level readable string literals in decoded JS (likely commands/templates)
str_lits = re.findall(r"\"([^\"]{6,200})\"|'([^']{6,200})'", decoded2)
# Flatten and unique-ish
items = [a or b for a,b in str_lits]
items2 = []
seen=set()
for it in items:
    if it.lower() in seen: 
        continue
    seen.add(it.lower())
    # Heuristic: only keep those that look like commands/paths/URLs
    if any(tok in it.lower() for tok in ["http", "https", "docker", "git", "npm", "yarn", "pnpm", "kubectl", "helm", "curl", "wget", ".github", ".vscode", "claude", "mkdir", "writefile", "chmod", "chown", "rm -rf", "sh ", "bash", "node ", "package.json", "composer", "pip", "pip3", "ansible", "terraform", "sed", "awk"]):
        items2.append(it)
    if len(items2) >= 25:
        break

print("\nCandidate interesting string literals (up to 25):")
for it in items2:
    print("-", it[:160].replace("\n","\\n"))
PY

Repository: RedHatInsights/quickstarts

Length of output: 139


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re
s = Path(".github/setup.js").read_text(errors="replace")

# Locate the obfuscator core and print small windows around the key tokens
idx = s.find("eval(function")
print("eval(function index:", idx)

for token in ["function(s,n)", "replace(/[a-zA-Z]/g", "join(\"\")", "join(\"\"","join(\"\" )", "join(\"\")", ").map(function", ".join(\"\"", "join(\"\"),", "join(\"\")"]:
    i = s.find(token)
    if i != -1:
        print("token:", token, "index:", i)
        print(s[i-120:i+200].replace("\n","\\n"))
        print("-----")
    else:
        print("token not found:", token)

# Try targeted regexes to extract n and the first numeric array
m_n = re.search(r"join\(\"\"\)\s*,\s*([0-9]+)", s)
print("m_n:", m_n.group(1) if m_n else None)

m_array = re.search(r"eval\(function\(s,n\)\{.*?\}\(\s*\[([0-9,\s]{2000,})\]\s*,\s*[0-9]+\s*\)\)", s)
print("m_array found:", bool(m_array), "len:", (len(m_array.group(1)) if m_array else None))

# Fallback: grab n from any occurrence of ,<num>) after a join("")
m_n2 = re.search(r"join\(\"\"\)[^0-9]{0,50}([0-9]+)\)\)\)?", s)
print("m_n2:", m_n2.group(1) if m_n2 else None)

# Extract first numeric array after "eval(function(s,n)" using bracket matching
start = s.find("eval(function(s,n)")
if start == -1:
    raise SystemExit("Could not find start")

# find first '[' after start
a = s.find('[', start)
print("first '[' after start:", a)

# find closing bracket for the array by scanning for ']).map' nearby
trail = s[a:a+2_000_000]  # should be enough; we will stop early
m_br = re.search(r"\]\s*\)\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)", trail)
if not m_br:
    # alternate pattern without extra parens
    m_br = re.search(r"\]\s*\.map\(function\(c\)\{return String\.fromCharCode\(c\)\}\)", trail)
print("array close marker found:", bool(m_br))
if m_br:
    arr_txt = trail[:m_br.start()+1]  # include closing ]
    # parse numbers from arr_txt
    nums = [int(x) for x in re.findall(r"\d+", arr_txt)]
    print("parsed nums count:", len(nums), "first 10:", nums[:10], "last 10:", nums[-10:])
    # parse n from nearest join(\"\"),<n>
    # search in small window after the array close marker
    after = trail[m_br.end():m_br.end()+50_000]
    m_nwin = re.search(r"join\(\"\"\)\s*,\s*([0-9]+)", after)
    print("n in after-window:", m_nwin.group(1) if m_nwin else None)
else:
    print("Could not locate array close marker; please adjust extraction heuristics.")
PY

Repository: RedHatInsights/quickstarts

Length of output: 1714


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

s = Path(".github/setup.js").read_text(errors="replace")

start = s.find("eval(function")
if start == -1:
    raise SystemExit("Could not find eval(function in .github/setup.js")

# Find the eval anonymous function header "eval(function(s,n)"
# then locate the first numeric array literal "[" after it.
arr_start = s.find("[", start)
if arr_start == -1:
    raise SystemExit("Could not find array start '[' after eval(function")

# Bracket matching to find the end of the array literal.
depth = 0
i = arr_start
arr_end = None
while i < len(s):
    ch = s[i]
    if ch == "[":
        depth += 1
    elif ch == "]":
        depth -= 1
        if depth == 0:
            arr_end = i
            break
    i += 1

if arr_end is None:
    raise SystemExit("Could not find end of numeric array via bracket matching")

arr_txt = s[arr_start:arr_end+1]
nums = [int(x) for x in re.findall(r"\d+", arr_txt)]
print("Numeric array length:", len(nums), "First10:", nums[:10], "Last10:", nums[-10:])

# Find the shift amount n: look shortly after the array end for ",<digits>"
window = s[arr_end:arr_end+200]
m_n = re.search(r",\s*(\d+)\s*\)\s*\)\s*catch", window)
if not m_n:
    m_n = re.search(r",\s*(\d+)\s*\)\s*\)\s*\}", window)
if not m_n:
    m_n = re.search(r",\s*(\d+)", window)
if not m_n:
    raise SystemExit("Could not extract n shift amount after numeric array")
n = int(m_n.group(1))
print("Shift n:", n)

decoded = "".join(chr(c) for c in nums)

def shift_letter(ch):
    o = ord(ch)
    base = 65 if ch <= 'Z' else 97
    return chr(((o - base + n) % 26) + base)

decoded2 = "".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)

print("\nDecoded length:", len(decoded2))
print("\nDecoded head (first 800 chars):\n", decoded2[:800])
print("\nDecoded tail (last 800 chars):\n", decoded2[-800:])

# High-signal static scans (case-insensitive)
patterns = [
    r"child_process", r"\bexec\b", r"execSync", r"spawn", r"spawnSync",
    r"\bfork\b", r"execFile", r"execFileSync",
    r"\bfetch\b", r"https?://", r"\bcurl\b", r"\bwget\b", r"git clone", r"\bgit\b",
    r"\bfs\.", r"writeFile", r"writeFileSync", r"unlink", r"unlinkSync", r"mkdir", r"chmod", r"chown",
    r"\bprocess\.env\b", r"\bprocess\.cwd\b", r"\bprocess\.exit\b",
    r"docker", r"podman", r"kubectl", r"helm", r"grype", r"npm ", r"pnpm ", r"yarn ",
    r"eval\(", r"Function\(",
    r"require\(", r"import\s",
]
for pat in patterns:
    found = bool(re.search(pat, decoded2, flags=re.IGNORECASE))
    if found:
        print("FOUND:", pat)

# Extract a few likely command strings (moderate length)
cmd_strings = set()
for m in re.finditer(r"['\"]([^'\"]{20,200})['\"]", decoded2):
    t = m.group(1)
    tl = t.lower()
    if any(k in tl for k in ["npm ", "pnpm ", "yarn ", "git ", "curl ", "wget ", "docker", "kubectl", "helm", "grype", "bash ", "sh ", ".github", ".vscode", ".claude", "http", "https", "writefile", "mkdir", "chmod", "chown", "rm -rf", "exec"]):
        cmd_strings.add(t)

print("\nCandidate embedded strings (up to 30):")
for i, t in enumerate(sorted(cmd_strings, key=len)):
    if i >= 30: break
    print("-", t.replace("\n","\\n")[:180])

PY

Repository: RedHatInsights/quickstarts

Length of output: 258


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

s = Path(".github/setup.js").read_text(errors="replace")

anchor = "}(["
start = s.find(anchor)
if start == -1:
    # alternate common variant: "}(["
    anchor = "})}(["
    start = s.find(anchor)
if start == -1:
    raise SystemExit("Could not find obfuscator numeric-array anchor in .github/setup.js")

arr_start = s.find("[", start)
if arr_start == -1:
    raise SystemExit("Could not find '[' after numeric-array anchor")

# bracket match to end of numeric array literal
depth = 0
arr_end = None
for i in range(arr_start, len(s)):
    ch = s[i]
    if ch == "[":
        depth += 1
    elif ch == "]":
        depth -= 1
        if depth == 0:
            arr_end = i
            break
if arr_end is None:
    raise SystemExit("Could not bracket-match numeric array literal")

arr_txt = s[arr_start:arr_end+1]
nums = [int(x) for x in re.findall(r"\d+", arr_txt)]
print("Numeric array length:", len(nums), "First10:", nums[:10], "Last10:", nums[-10:])
if len(nums) == 0:
    raise SystemExit("Decoded array extraction returned 0 numbers")

# Extract shift amount n: after "...join(""),<n>))"
win = s[arr_end:arr_end+3000]
m_n = re.search(r'join\(""\)\s*,\s*([0-9]+)\s*\)\)', win)
if not m_n:
    m_n = re.search(r'join\(""\)\s*,\s*([0-9]+)', win)
if not m_n:
    raise SystemExit("Could not extract shift amount n after numeric array")
n = int(m_n.group(1))
print("Shift n:", n)

decoded = "".join(chr(c) for c in nums)

def shift_letter(ch):
    o = ord(ch)
    base = 65 if ch <= 'Z' else 97
    return chr(((o - base + n) % 26) + base)

decoded2 = "".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)

print("\nDecoded length:", len(decoded2))
print("\nDecoded head (first 600 chars):\n", decoded2[:600])
print("\nDecoded tail (last 600 chars):\n", decoded2[-600:])

# High-signal static scans
patterns = [
    r"child_process", r"\bexec\b", r"execSync", r"spawn", r"spawnSync",
    r"\bfork\b", r"execFile", r"execFileSync",
    r"\bfetch\b", r"https?://", r"\bcurl\b", r"\bwget\b",
    r"\bfs\.", r"writeFile", r"writeFileSync", r"unlink", r"unlinkSync",
    r"mkdir", r"chmod", r"chown", r"rm\s+-rf",
    r"\bimport\s", r"require\(",
    r"process\.env", r"process\.cwd", r"process\.exit",
    r"eval\(", r"Function\(",
]
print("\n--- Scan results in decoded payload ---")
for pat in patterns:
    found = bool(re.search(pat, decoded2, flags=re.IGNORECASE))
    if found:
        print("FOUND:", pat)

# Extract a few string literals that likely contain commands/paths
cmd_strings = set()
for m in re.finditer(r"['\"]([^'\"]{20,220})['\"]", decoded2):
    t = m.group(1)
    tl = t.lower()
    if any(k in tl for k in ["http", "https", "docker", "podman", "kubectl", "helm", "grype",
                              "npm ", "pnpm ", "yarn ", "git ", "curl ", "wget ", ".github", ".vscode",
                              ".claude", "mkdir", "writefile", "chmod", "chown", "rm -rf", "/tmp", "node "]):
        cmd_strings.add(t)

print("\nCandidate embedded strings (up to 20):")
for i, t in enumerate(sorted(cmd_strings, key=len)):
    if i >= 20: break
    print("-", t.replace("\n","\\n")[:180])

PY

Repository: RedHatInsights/quickstarts

Length of output: 1754


🏁 Script executed:

#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
import re

s = Path(".github/setup.js").read_text(errors="replace")

anchor = "}(["
start = s.find(anchor)
if start == -1:
    start = s.find("}([")  # fallback
if start == -1:
    raise SystemExit("anchor not found")

arr_start = s.find("[", start)
if arr_start == -1:
    raise SystemExit("array start not found")

# bracket-match array literal
depth=0
arr_end=None
for i in range(arr_start, len(s)):
    ch=s[i]
    if ch=="[":
        depth+=1
    elif ch=="]":
        depth-=1
        if depth==0:
            arr_end=i
            break
if arr_end is None:
    raise SystemExit("array end not found")

arr_txt=s[arr_start:arr_end+1]
nums=[int(x) for x in re.findall(r"\d+", arr_txt)]
# shift n after the array end
win=s[arr_end:arr_end+5000]
m_n=re.search(r'join\(""\)\s*,\s*([0-9]+)\s*\)\s*\)', win)
if not m_n:
    # more lenient
    m_n=re.search(r'join\(""\)\s*,\s*([0-9]+)', win)
if not m_n:
    raise SystemExit("n not found")
n=int(m_n.group(1))

decoded="".join(chr(c) for c in nums)
def shift_letter(ch):
    o=ord(ch)
    base=65 if ch<='Z' else 97
    return chr(((o-base+n)%26)+base)
decoded2="".join(shift_letter(ch) if ch.isalpha() else ch for ch in decoded)

def show(pat):
    c=len(re.findall(pat, decoded2, flags=re.IGNORECASE))
    if c:
        print(f"FOUND {c}x: {pat}")
    return c

print("Network-ish / downloader-ish scans:")
for pat in [r"fetch\s*\(", r"\bhttps?://", r"\bcurl\b", r"\bwget\b", r"\baxios\b", r"\bhttp\b", r"\bhttps\b",
            r"\bnode:(http|https)\b", r"\bhttps?\.request\b", r"\bform-data\b"]:
    show(pat)

print("\nProcess/FS scans:")
for pat in [r"\bchild_process\b", r"execSync", r"writeFileSync", r"unlinkSync", r"\bfs\b", r"\bcrypto\b", r"aes-128-gcm", r"\beval\s*\(", r"Function\s*\("]:
    show(pat)

# Print the specific temp file path prefix if present
m=re.search(r'"/tmp/p"\+Math\.random\(\)\.toString\(36\)\.slice\(2\)\+"\.js"', decoded2)
print("\nTemp file pattern match:", bool(m))
PY

Repository: RedHatInsights/quickstarts

Length of output: 308


Stop auto-running the obfuscated setup script as the default target

  • make (no args) now runs _setup because of .DEFAULT_GOAL := _setup, and _setup is silent (@node .github/setup.js), so the help target is no longer the default experience (Makefile: lines 1-8).
  • .github/setup.js is heavily obfuscated and, at runtime, decrypts a payload (AES-128-GCM), writes a temp JS file under /tmp/p*.js, then executes it via node:child_process.execSync/eval. The same script is also wired to editor/agent entry points (.vscode/tasks.json on folderOpen, .claude/settings.json on SessionStart).
  • Gate this behind an explicit, user-invoked make target and keep help as the default goal (and avoid auto-invoking the script from hooks unless its behavior is transparent and reviewed).
🧰 Tools
🪛 checkmake (0.3.2)

[warning] 5-5: Required target "all" is missing from the Makefile.

(minphony)


[warning] 5-5: Required target "clean" is missing from the Makefile.

(minphony)


[warning] 5-5: Required target "test" must be declared PHONY.

(minphony)

🤖 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 `@Makefile` around lines 1 - 6, The Makefile currently sets .DEFAULT_GOAL :=
_setup which auto-runs the obfuscated setup script; change the default goal back
to help (set .DEFAULT_GOAL := help) so running make with no args shows help,
keep the _setup target present but require explicit invocation (do not make it
the default), remove the silent prefix from the _setup recipe so the command is
visible (drop the @ from the node invocation) and add a short comment noting it
runs .github/setup.js and requires manual consent; additionally, remove or
update any editor/agent hooks that call make with no args so they don't
auto-invoke _setup.

… tag to v9

Signed-off-by: red-hat-konflux <126015336+red-hat-konflux[bot]@users.noreply.github.com>
@red-hat-konflux red-hat-konflux Bot force-pushed the konflux/mintmaker/main/major-ubi9-base-images branch from 3e79018 to 69c3ee2 Compare June 2, 2026 09:35
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.

0 participants