Skip to content
Open
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
18 changes: 18 additions & 0 deletions .github/actions/install-yq/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Install yq
description: Install mikefarah/yq at a pinned version

inputs:
version:
description: "yq version to install"
required: false
default: "4.53.3"

runs:
using: composite
steps:
- name: Install yq v${{ inputs.version }}
shell: bash
run: |
sudo wget -qO /usr/local/bin/yq \
"https://github.com/mikefarah/yq/releases/download/v${{ inputs.version }}/yq_linux_amd64"
sudo chmod +x /usr/local/bin/yq
Comment on lines +16 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file =="
cat -n .github/actions/install-yq/action.yaml

echo "== usages =="
rg -n "install-yq|yq_linux_amd64|yq:" .github -S || true

echo "== workflow files relevant =="
git ls-files .github | sed -n '1,120p'

Repository: Kuadrant/authorino

Length of output: 1799


Verify the yq binary before installing it with sudo.

The action downloads an executable directly into /usr/local/bin without integrity validation, and it is used by release/version-gate workflows. Add the upstream SHA-256 for the pinned release asset and check it before chmod.

🤖 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/actions/install-yq/action.yaml around lines 16 - 18, Add SHA-256
verification to the yq installation steps: download the release asset to a
temporary location, validate it against the upstream checksum for the pinned
version before installation, then move it to /usr/local/bin/yq and run chmod
only after verification succeeds. Update the action inputs or workflow
configuration as needed to provide the expected checksum.

31 changes: 31 additions & 0 deletions .github/scripts/parse-version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -euo pipefail

RELEASE_YAML="${1:-release.yaml}"

if [[ ! -f "$RELEASE_YAML" ]]; then
echo "::error::File not found: $RELEASE_YAML"
exit 1
fi

VERSION=$(yq '.authorino.version' "$RELEASE_YAML")
if [[ -z "$VERSION" || "$VERSION" == "null" ]]; then
echo "::error::No version found in $RELEASE_YAML under authorino.version"
exit 1
fi

if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
echo "::error::Invalid semver: $VERSION"
exit 1
fi
Comment on lines +17 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Use one SemVer-compliant validator across both release paths. The duplicated regex accepts invalid versions such as 01.2.3 and rejects valid versions such as 1.2.3-rc-1; the two paths can therefore create or reject releases inconsistently.

  • .github/scripts/parse-version.sh#L17-L20: replace the regex with a SemVer-compliant validator and ensure parsing handles any supported prerelease/build components.
  • .github/workflows/pre-release.yaml#L33-L45: call the shared parser/validator rather than maintaining a second regex.
📍 Affects 2 files
  • .github/scripts/parse-version.sh#L17-L20 (this comment)
  • .github/workflows/pre-release.yaml#L33-L45
🤖 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/scripts/parse-version.sh around lines 17 - 20, Use a single
SemVer-compliant validation and parsing path: update
.github/scripts/parse-version.sh lines 17-20 to validate supported prerelease
and build metadata while rejecting invalid numeric components such as 01.2.3,
and update .github/workflows/pre-release.yaml lines 33-45 to call the shared
parser/validator instead of applying its own regex.


MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3 | cut -d- -f1)
RELEASE_BRANCH="release-${MAJOR}.${MINOR}"

echo "version=$VERSION" >> "${GITHUB_OUTPUT:-/dev/stdout}"
echo "major=$MAJOR" >> "${GITHUB_OUTPUT:-/dev/stdout}"
echo "minor=$MINOR" >> "${GITHUB_OUTPUT:-/dev/stdout}"
echo "patch=$PATCH" >> "${GITHUB_OUTPUT:-/dev/stdout}"
echo "release-branch=$RELEASE_BRANCH" >> "${GITHUB_OUTPUT:-/dev/stdout}"
45 changes: 45 additions & 0 deletions .github/scripts/validate-release-yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail

BRANCH="${1:?Branch name required}"
ORG="${2:-Kuadrant}"
RELEASE_YAML="${3:-release.yaml}"

if [[ ! -f "$RELEASE_YAML" ]]; then
echo "::error::File not found: $RELEASE_YAML"
exit 1
fi

VERSION=$(yq '.authorino.version' "$RELEASE_YAML")

if [[ "$BRANCH" != "main" && "$VERSION" == "0.0.0" ]]; then
echo "::error::release.yaml version is 0.0.0 on branch '$BRANCH' -- must specify a release version on non-main branches"
exit 1
fi
Comment on lines +13 to +18

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Validate the version format, not only the 0.0.0 sentinel.

release.yaml with authorino.version: invalid passes this script on a release PR. Invoke the shared version parser here (or a shared validator) so the Version Gate enforces its declared SemVer contract before release orchestration.

🤖 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/scripts/validate-release-yaml.sh around lines 13 - 18, Update the
version validation in validate-release-yaml.sh to invoke the shared version
parser or validator for VERSION, enforcing the declared SemVer contract before
release orchestration. Preserve the existing non-main branch rejection for the
0.0.0 sentinel while ensuring invalid values such as “invalid” fail validation.


ERRORS=0
ENTRIES=$(yq -o=json '.dependencies // {} | to_entries[]' "$RELEASE_YAML" 2>/dev/null || true)
if [[ -n "$ENTRIES" ]]; then
Comment on lines +21 to +22

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

yq --version

tmp_file="$(mktemp)"
trap 'rm -f "$tmp_file"' EXIT

cat >"$tmp_file" <<'YAML'
authorino:
  version: "1.2.3"
dependencies: invalid
YAML

if yq -e '(.dependencies == null) or (.dependencies | type == "!!map")' "$tmp_file" >/dev/null; then
  echo "Expected a scalar dependencies value to fail validation" >&2
  exit 1
fi

Repository: Kuadrant/authorino

Length of output: 196


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf 'Repository files matching validate-release-yaml.sh:\n'
fd -a 'validate-release-yaml\.sh$' . || true

printf '\nFile context:\n'
if [ -f .github/scripts/validate-release-yaml.sh ]; then
  cat -n .github/scripts/validate-release-yaml.sh
fi

printf '\nSearch for validate-release-yaml usage:\n'
rg -n "validate-release-yaml|RELEASE_YAML|dependencies" .github test . 2>/dev/null | head -200

Repository: Kuadrant/authorino

Length of output: 3776


🌐 Web query:

mikefarah yq .dependencies to_entries mapping error || true behavior

💡 Result:

In mikefarah/yq, the to_entries operator is designed to convert maps and arrays into an array of key-value pair objects [1][2]. The behavior you are encountering—where commands like ... | to_entries || true do not suppress errors as expected—is rooted in how yq's internal expression engine handles errors and pipelines, which differs from standard shell behavior [3][4]. Key points regarding this behavior include: 1. Shell Pipe vs. yq Expression: The || true construct is a shell-level operator. If yq encounters a fatal error during the evaluation of its internal expression (such as an invalid path traversal or a type error), the error message is often generated and printed by the yq binary itself before the shell even receives an exit code, or the error might occur within the internal pipeline of yq, which the shell's || cannot intercept [3][5]. 2. yq Error Handling: According to official documentation, yq is designed to display error messages alongside the results of the closest valid filter [5]. When an expression chain fails (e.g., trying to access keys on a non-mappable or non-sequence type), yq may return a non-zero exit status [5]. To effectively suppress these, ensure your yq expression itself is robust (e.g., using select() or has() to verify structure before piping into to_entries) rather than relying on external shell error handling [3]. 3. Common Cause: Errors with to_entries often stem from attempting to convert types that are not mappings or sequences [6][7]. If a path in your expression resolves to null or a scalar value instead of a map, to_entries will trigger an error (e.g., ... has no keys) because it expects a structure that can be iterated as a collection [6][7]. To mitigate these errors, you can use conditional filtering to ensure the input to to_entries is a valid collection: - Use select(): Filter the input to ensure it is not null or empty before calling to_entries [3]. Example: yq '.dependencies | select(. != null) | to_entries' - Use has(): Check for the existence of the key if you are traversing a variable [3]. Example: yq '... | select(has("dependencies")) | .dependencies | to_entries' If you are trying to handle "missing" data gracefully, select is the preferred idiom in yq to avoid attempting operations on invalid nodes [3].

Citations:


Reject invalid dependencies structures.

If .dependencies is not a mapping or null, the query cannot convert to entries. Drop || true so yq failures stop validation, and require (.dependencies == null) or (.dependencies | type == "!!map") before enumerating entries.

🤖 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/scripts/validate-release-yaml.sh around lines 21 - 22, Update the
dependencies validation flow in validate-release-yaml.sh to reject non-mapping,
non-null .dependencies values before enumerating entries. Remove the || true
suppression from the ENTRIES yq command so query failures propagate, and add a
guard requiring .dependencies to be null or type !!map before running
to_entries.

while IFS= read -r entry; do
dep=$(echo "$entry" | jq -r '.key')
dep_version=$(echo "$entry" | jq -r '.value')
if [[ "$dep_version" != "0.0.0" && "$dep_version" != "null" && -n "$dep_version" ]]; then
draft_status=$(gh release view "v${dep_version}" --repo "${ORG}/${dep}" --json isDraft -q '.isDraft' 2>/dev/null) || {
echo "::error::Dependency '${dep}' targets version '${dep_version}', but release v${dep_version} does not exist in ${ORG}/${dep}"
ERRORS=$((ERRORS + 1))
continue
}
if [[ "$draft_status" == "true" ]]; then
echo "::error::Dependency '${dep}' targets version '${dep_version}', but release v${dep_version} in ${ORG}/${dep} is a draft"
ERRORS=$((ERRORS + 1))
fi
fi
done < <(echo "$ENTRIES" | jq -c '.')
fi

if [[ "$ERRORS" -gt 0 ]]; then
echo "::error::release.yaml validation failed with ${ERRORS} dependency error(s)"
exit 1
fi

echo "release.yaml validation passed"
23 changes: 19 additions & 4 deletions .github/workflows/build-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ on:
- 'main'
- 'master'
workflow_dispatch: {}
workflow_call:
inputs:
version:
description: "Release version (e.g. 0.26.0)"
type: string
required: true
ref:
description: "Git ref to build from (e.g. v0.26.0)"
type: string
required: true

env:
IMG_TAGS: ${{ github.sha }}
Expand All @@ -29,7 +39,10 @@ jobs:
- name: Set Authorino build info
id: build-info
run: |
if [[ ${GITHUB_REF_NAME/\//-} =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then
if [[ -n "${{ inputs.version }}" ]]; then
echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
echo "version_tag=v${{ inputs.version }}" >> $GITHUB_OUTPUT
elif [[ ${GITHUB_REF_NAME/\//-} =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then
Comment on lines +42 to +45

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow target =="
sed -n '1,120p' .github/workflows/build-images.yaml 2>/dev/null || true

echo
echo "== all inputs.version occurrences in workflows =="
rg -n "inputs\.version|GITHUB_OUTPUT|GITHUB_REF_NAME" .github/workflows -S

echo
echo "== GitHub Actions syntax/security scan references (zizmor, semgrep, actionlint) =="
sed -n '1,80p' README.md 2>/dev/null || true
rg -n "zizmor|actionlint|semgrep|github-actions|workflow\\/" .github README.md 2>/dev/null || true

echo
echo "== shell injection probe for direct string interpolation in quoted expansion =="
python3 - <<'PY'
import subprocess, tempfile, os
evil = 'README.md;false "x=1"'
script = f'''set -e
if [[ -n "READER_VERSION" ]]; then
  echo "readme=$READER_VERSION" >> "$GITHUB_OUTPUT"
elif [[ ${"{GITHUB_REF_NAME\"}"}.x =~ ^v[0-9]+ ]]; then
  echo "ok=malicious" >> "$GITHUB_OUTPUT"
fi
'''
env = dict(os.environ, GITHUB_OUTPUT='tmp', GITHUB_REF_NAME='v1.2.3')
result = subprocess.run(['bash','/bin/echo','README.md;false "x=1"'], text=True, capture_output=True)
# direct example:
src = f'''if [[ -n "{[evil[0]]*3}" ]]; then echo "ok"; fi'''
PY

Repository: Kuadrant/authorino

Length of output: 15101


🌐 Web query:

zizmor github-actions GitHub Actions security audit templated expressions shell injection GITHUB_OUTPUT

💡 Result:

zizmor is a security-focused static analysis tool designed specifically for auditing GitHub Actions workflows and configurations [1][2]. It helps identify common security vulnerabilities, including template injection and unsafe handling of workflow context variables [2]. Regarding the specific security concerns you mentioned: Template Injection and Shell Injection zizmor detects dangerous usage of templated expressions (${{ ... }}) [2]. A primary risk in GitHub Actions occurs when attacker-controlled input—such as pull request titles, branch names, or issue content—is directly interpolated into a run: step using the ${{ ... }} syntax [3][4]. Because this interpolation happens before the shell executes the command, an attacker can inject malicious shell code (shell injection) [3][4]. zizmor flags these instances to encourage safer alternatives, such as assigning untrusted input to environment variables via the env: block and referencing them as standard shell variables (e.g., "$MY_VAR") [3][4]. GITHUB_OUTPUT Injection zizmor also helps identify issues related to $GITHUB_OUTPUT [5]. Writing unsanitized, user-controllable input to the $GITHUB_OUTPUT file is a security risk because it allows an attacker to inject additional output keys or smuggle newline-delimited payloads that downstream steps may inadvertently consume and execute [6]. This is effectively a variant of environment file injection [6]. To mitigate this, security best practices (which zizmor-related documentation emphasizes) advise against serializing untrusted context directly to $GITHUB_OUTPUT, recommending instead that inputs be validated, sanitized, or handled via environment variables that do not risk premature shell or interpreter execution [6]. How to Use zizmor zizmor can be run locally or integrated into your CI/CD pipelines [1][7]. - Integration: The simplest way to integrate it is via the zizmor-action [7][8]. It supports uploading results as SARIF files for GitHub Advanced Security users [7][8]. - Configuration: You can run it offline, customize its sensitivity (e.g., using different personas), and output results in various formats like SARIF, JSON, or plain text [1][5][9]. For detailed information on the specific rules implemented in the tool, refer to the official zizmor audit documentation [5].

Citations:


🌐 Web query:

GitHub Actions zizmor rule context-in-expression GITHUB_OUTPUT quote expressions

💡 Result:

The zizmor tool is a static analysis security scanner for GitHub Actions workflows that helps identify vulnerabilities, including template injection risks [1][2]. While there is no specific rule named "context-in-expression" in the public documentation, zizmor utilizes an internal expression analysis engine to trace how data flows from workflow contexts (like job outputs or step inputs) into potentially executable areas [3][4][5]. The core security concern zizmor addresses in this area is template injection, where untrusted or attacker-controlled data from contexts is used in a way that allows arbitrary code execution [5][2]. Zizmor's analysis engine tracks "contexts" (e.g., github.actor, inputs.foo, or outputs from steps) as they flow through expressions [3][4]. Regarding GITHUB_OUTPUT and quoting, GitHub Actions workflows often use GITHUB_OUTPUT to set environment variables for subsequent steps [6][7]. A common security best practice—and a pattern that static analysis tools like zizmor encourage—is to treat output data as untrusted input. When such data is later used in an expression, failing to properly quote or sanitize the expression can create injection vectors if the output contains characters that alter the structure of the YAML or the expression itself [5]. Zizmor evaluates whether an expression is "safe" by determining if it is composed entirely of static, non-attacker-controlled elements (like string literals defined in the workflow) or if it incorporates variable context data that could be maliciously influenced [5]. If your workflow uses expressions involving GITHUB_OUTPUT or similar context-derived values, zizmor may flag these if it determines that the data flows directly into an execution context without sufficient insulation or structural safety [3][5]. To remediate such findings, ensure that any dynamic output being referenced is handled securely, such as by using JSON functions to safely pass complex data or by ensuring that string concatenation does not lead to unintended code evaluation [8][5].

Citations:


Avoid interpolating inputs.version directly in the shell script.

GitHub Actions substitutes ${{ inputs.version }} before Bash parses the step, so a crafted version value can inject shell commands in the if guard and append forged entries to $GITHUB_OUTPUT. Pass it through env, validate the expected version shape, and write quoted values with printf.

🧰 Tools
🪛 zizmor (1.28.0)

[error] 42-42: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 43-43: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 44-44: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)

🤖 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/build-images.yaml around lines 42 - 45, Update the
version-handling step around the inputs.version branch to pass the input through
the step environment instead of interpolating it into Bash. Validate the
environment value against the expected version format before using it, and write
version and version_tag outputs with quoted printf calls to prevent shell
injection and forged output entries.

Source: Linters/SAST tools

tag=${GITHUB_REF_NAME/\//-}
echo "version=${tag#v}" >> $GITHUB_OUTPUT
echo "version_tag=${tag}" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -62,6 +75,8 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # ratchet:actions/checkout@v4
with:
ref: ${{ inputs.ref || '' }}
Comment on lines +78 to +79

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow files =="
git ls-files .github/workflows

echo "== target file outline =="
wc -l .github/workflows/build-images.yaml
sed -n '1,220p' .github/workflows/build-images.yaml

echo "== repo workflows mentioning image provenance/github-sha/git_sha =="
rg -n "github\.sha|git_sha|git rev-parse|inputs\.ref|workflow_dispatch|on:\s*$|uses: .*build-images" .github/workflows -S

Repository: Kuadrant/authorino

Length of output: 9773


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== release workflow around reusable call =="
sed -n '70,110p' .github/workflows/release.yaml

echo "== release triggers and version/tag paths =="
sed -n '1,90p' .github/workflows/release.yaml

echo "== context from workflow_call docs via public source if available; search local docs =="
rg -n "workflow_call|caller workflow|github\.sha|GITHUB_SHA|inputs\.ref" .github README.md 2>/dev/null || true

Repository: Kuadrant/authorino

Length of output: 4855


🌐 Web query:

GitHub Actions reusable workflows inputs refs github.sha documentation

💡 Result:

In GitHub Actions, the github context variables—including github.sha—are always associated with the caller workflow, not the reusable workflow [1][2]. Consequently, github.sha inside a reusable workflow refers to the commit SHA of the caller's repository, not the repository that contains the reusable workflow [3][2]. If you need to identify the specific repository or commit SHA of the reusable workflow itself, you should use the job context [4]. The following properties are available: - job.workflow_repository: The owner/repo of the repository containing the workflow file that defines the current job [4]. - job.workflow_sha: The commit SHA of the workflow file that defines the current job [4]. For example, if you are using actions/checkout within a reusable workflow and want to ensure you check out the code from the reusable workflow's own repository and commit, you can use these properties: - uses: actions/checkout@v4 with: repository: ${{ job.workflow_repository }} ref: ${{ job.workflow_sha }} This approach resolves issues where reusable workflows might otherwise default to the caller's context or the default branch of the reusable repository [4]. If you need to pass specific version information as an input to a reusable workflow, it is common practice to define an explicit input (e.g., gh-workflows-ref) in your workflow_call configuration, which the caller must manually populate [3].

Citations:


🌐 Web query:

GitHub Actions reusable workflows caller repository github.sha reusable workflow GitHub docs

💡 Result:

In GitHub Actions, the github context within a reusable workflow is always associated with the caller workflow, not the reusable workflow itself [1][2][3]. Consequently, github.sha will return the commit SHA of the caller repository's event that triggered the workflow run, not the SHA of the reusable workflow [4][5]. To access information about the reusable workflow's own repository and commit SHA, you should use the job context properties [5]. These properties were specifically introduced to provide details about the workflow file that defines the current job [5]: - job.workflow_sha: The commit SHA of the workflow file that defines the current job [5]. - job.workflow_repository: The owner/repo of the repository containing the workflow file that defines the current job [5]. - job.workflow_ref: The full ref of the workflow file that defines the current job [5]. - job.workflow_file_path: The file path of the workflow file that defines the current job, relative to the repository root [5]. These properties are particularly useful when a reusable workflow needs to check out its own source code (e.g., to access co-located scripts or configuration files) [6][5]. You can use them with the actions/checkout action as follows [6]: - uses: actions/checkout@v4 with: repository: ${{ job.workflow_repository }} ref: ${{ job.workflow_sha }} For additional context, while github.sha refers to the trigger event of the caller workflow, github.workflow_sha refers to the SHA of the workflow file of the top-most (caller) workflow, which is distinct from the job.workflow_sha of a reusable workflow [5][7].

Citations:


Derive image provenance from the checked-out ref.

build-images.yaml checks out ${{ inputs.ref || '' }}, but prepare.git_sha, ${{ env.IMG_TAGS }}, and the raw SHA manifest tag still use ${{ github.sha }}. In workflow_call, ${{ github.sha }} is set by the caller workflow context, so in the release path a build can run with git_sha=v0.26.0 while the image is tagged with the release-workflow’s SHA. Derive the SHA with git rev-parse HEAD after checking out the requested ref and use that output for git_sha; avoid relying on ${{ github.sha }} for the SHA tag.

🧰 Tools
🪛 zizmor (1.28.0)

[warning] 76-79: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/build-images.yaml around lines 78 - 79, Update the image
build workflow after checkout to derive the commit SHA from the checked-out
repository using git rev-parse HEAD. Reuse this derived SHA for prepare.git_sha,
env.IMG_TAGS, and the raw SHA manifest tag, replacing github.sha so all
provenance and image tags reflect inputs.ref.

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # ratchet:docker/setup-buildx-action@v3
- name: Login to registry
Expand Down Expand Up @@ -119,9 +134,9 @@ jobs:
with:
images: ${{ env.IMG_REGISTRY_HOST }}/${{ env.IMG_REGISTRY_ORG }}/authorino
tags: |
type=raw,value=${{ github.ref_name }},enable={{is_not_default_branch}}
type=raw,value=${{ github.sha }},enable={{is_default_branch}}
type=raw,value=latest,enable={{is_default_branch}}
type=raw,value=${{ needs.prepare.outputs.version_tag }}
type=raw,value=${{ github.sha }},enable=${{ needs.prepare.outputs.version_tag == 'latest' }}
type=raw,value=latest,enable=${{ needs.prepare.outputs.version_tag == 'latest' }}
- name: Login to registry
if: ${{ !env.ACT }}
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # ratchet:docker/login-action@v3
Expand Down
141 changes: 141 additions & 0 deletions .github/workflows/pre-release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: Pre-release

on:
workflow_dispatch:
inputs:
version:
description: "Release version (semver, e.g. 1.5.0)"
required: true
type: string
source-branch:
description: "Branch to base the pre-release changes on (default: main)"
required: false
type: string
default: "main"

permissions:
contents: write
pull-requests: write

jobs:
setup:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.validate.outputs.version }}
release-branch: ${{ steps.validate.outputs.release-branch }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # ratchet:actions/checkout@v4
with:
ref: ${{ inputs.source-branch }}
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}

- name: Validate version format
id: validate
run: |
VERSION="${{ inputs.version }}"
if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
echo "::error::Invalid semver version: $VERSION"
exit 1
fi
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
RELEASE_BRANCH="release-${MAJOR}.${MINOR}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "release-branch=$RELEASE_BRANCH" >> "$GITHUB_OUTPUT"

- name: Create or verify release branch
run: |
RELEASE_BRANCH="${{ steps.validate.outputs.release-branch }}"
if git ls-remote --exit-code origin "refs/heads/${RELEASE_BRANCH}" >/dev/null 2>&1; then
echo "Release branch '${RELEASE_BRANCH}' already exists"
else
echo "Creating release branch '${RELEASE_BRANCH}' from '${{ inputs.source-branch }}'"
git checkout -b "${RELEASE_BRANCH}"
git push origin "${RELEASE_BRANCH}"
fi

prepare-release:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # ratchet:actions/checkout@v4
with:
ref: ${{ needs.setup.outputs.release-branch }}
fetch-depth: 0

- name: Create pre-release branch
run: |
PRE_RELEASE_BRANCH="pre-release-v${{ needs.setup.outputs.version }}"
if git ls-remote --exit-code origin "refs/heads/${PRE_RELEASE_BRANCH}" >/dev/null 2>&1; then
echo "::error::Pre-release branch '${PRE_RELEASE_BRANCH}' already exists. Delete it first or use a different version."
exit 1
fi
git checkout -b "${PRE_RELEASE_BRANCH}"

- uses: ./.github/actions/install-yq

- name: Update release.yaml
run: |
VERSION="${{ needs.setup.outputs.version }}"
yq -i ".authorino.version = \"${VERSION}\"" release.yaml

- name: Set up Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # ratchet:actions/setup-go@v5
with:
go-version-file: go.mod

- name: Run code generation
run: |
make generate
make manifests

- name: Commit and push changes
run: |
VERSION="${{ needs.setup.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add -A
if git diff --cached --quiet; then
echo "No changes to commit"
else
git commit -m "chore: prepare release v${VERSION}"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Missing the sign-off. Won't this fail the DCO check?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Could find documentation around this, but with the help of cluade found it the actions source. The check is skipped of merge commits, and for accounts that are marked as bots. Could there be a question over should that be case, possible, but that is why it wont fail the check.

https://github.com/dcoapp/app/blob/main/lib/dco.js#L21-L25

fi
git push origin "pre-release-v${VERSION}"

open-pr:
needs: [setup, prepare-release]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # ratchet:actions/checkout@v4

- name: Open pull request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION="${{ needs.setup.outputs.version }}"
RELEASE_BRANCH="${{ needs.setup.outputs.release-branch }}"

gh pr create \
--base "${RELEASE_BRANCH}" \
--head "pre-release-v${VERSION}" \
--title "Release v${VERSION}" \
--body "$(cat <<EOF
## Release v${VERSION}

This PR prepares the release of v${VERSION}.

### Pre-release changes
- Updated \`release.yaml\` version to \`${VERSION}\`
- Ran \`make generate\` and \`make manifests\`

### Checklist
- [ ] Version numbers are correct
- [ ] All pre-release modifications look correct
- [ ] CI checks pass
- [ ] Version gate check passes

### Next steps
After merging this PR, run the **Release** workflow with branch \`${RELEASE_BRANCH}\`.
EOF
)"
Loading
Loading