-
Notifications
You must be signed in to change notification settings - Fork 44
Add two-phase release workflow #634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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 | ||
|
|
||
| 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}" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #!/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 | ||
|
|
||
| DEPS=$(yq '.dependencies | keys | .[]' "$RELEASE_YAML" 2>/dev/null || true) | ||
| for dep in $DEPS; do | ||
| dep_version=$(yq ".dependencies.${dep}" "$RELEASE_YAML") | ||
| if [[ "$dep_version" != "0.0.0" && "$dep_version" != "null" && -n "$dep_version" ]]; then | ||
| if ! gh release view "v${dep_version}" --repo "${ORG}/${dep}" &>/dev/null; then | ||
| echo "::error::Dependency '${dep}' targets version '${dep_version}', but release v${dep_version} does not exist in ${ORG}/${dep}" | ||
| exit 1 | ||
| fi | ||
| fi | ||
| done | ||
|
|
||
| echo "release.yaml validation passed" | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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 }} | ||||||||||||||||||||||||||||||||||||
|
|
@@ -26,7 +36,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
+39
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🔴 Critical 🧩 Analysis chain🏁 Script executed: cat -n .github/workflows/build-images.yaml | sed -n '1,50p'Repository: Kuadrant/authorino Length of output: 2070 🏁 Script executed: cat -n .github/workflows/build-images.yaml | sed -n '9,18p;75,76p;130,132p'Repository: Kuadrant/authorino Length of output: 837 🏁 Script executed: # Check if there are any uses of inputs.version elsewhere in the workflow
rg 'inputs\.version' .github/workflows/build-images.yamlRepository: Kuadrant/authorino Length of output: 347 Harden Lines 39–41 interpolate Suggested fix - name: Set Authorino build info
id: build-info
+ env:
+ INPUT_VERSION: ${{ inputs.version }}
run: |
- if [[ -n "${{ inputs.version }}" ]]; then
- echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT
- echo "version_tag=v${{ inputs.version }}" >> $GITHUB_OUTPUT
+ if [[ -n "$INPUT_VERSION" ]]; then
+ if ! [[ "$INPUT_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?$ ]]; then
+ echo "::error::Invalid version input: $INPUT_VERSION"
+ exit 1
+ fi
+ printf 'version=%s\n' "$INPUT_VERSION" >> "$GITHUB_OUTPUT"
+ printf 'version_tag=v%s\n' "$INPUT_VERSION" >> "$GITHUB_OUTPUT"
elif [[ ${GITHUB_REF_NAME/\/,-} =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.26.1)[error] 39-39: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [error] 40-40: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [error] 41-41: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||
| tag=${GITHUB_REF_NAME/\//-} | ||||||||||||||||||||||||||||||||||||
| echo "version=${tag#v}" >> $GITHUB_OUTPUT | ||||||||||||||||||||||||||||||||||||
| echo "version_tag=${tag}" >> $GITHUB_OUTPUT | ||||||||||||||||||||||||||||||||||||
|
|
@@ -59,6 +72,8 @@ jobs: | |||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||
| - name: Check out code | ||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||
| ref: ${{ inputs.ref || '' }} | ||||||||||||||||||||||||||||||||||||
| - name: Set up Docker Buildx | ||||||||||||||||||||||||||||||||||||
| uses: docker/setup-buildx-action@v3 | ||||||||||||||||||||||||||||||||||||
| - name: Login to registry | ||||||||||||||||||||||||||||||||||||
|
|
@@ -112,9 +127,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@v3 | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| 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@v4 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major 🧩 Analysis chain🏁 Script executed: cat -n .github/workflows/pre-release.yaml | sed -n '20,115p'Repository: Kuadrant/authorino Length of output: 4142 Pin all action references to immutable commit SHAs. Lines 27, 62, 82, and 108 use mutable version tags ( 🧰 Tools🪛 zizmor (1.26.1)[warning] 27-31: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) [error] 27-27: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| 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@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}" | ||
|
|
||
| - 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@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}" | ||
| fi | ||
| git push origin "pre-release-v${VERSION}" | ||
|
|
||
| open-pr: | ||
| needs: [setup, prepare-release] | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: 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 | ||
| )" | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,133 @@ | ||||||||||||||||||||||||||||||
| name: Release | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||
| inputs: | ||||||||||||||||||||||||||||||
| release-branch: | ||||||||||||||||||||||||||||||
| description: "Release branch (e.g. release-1.5)" | ||||||||||||||||||||||||||||||
| required: true | ||||||||||||||||||||||||||||||
| type: string | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Reduce workflow token scope to least privilege.
Suggested fix permissions:
- contents: write
+ contents: read
jobs:
+ tag:
+ permissions:
+ contents: write
+ needs: [read-version, smoke-tests]
+ runs-on: ubuntu-latest
+ steps:
+ ...
+
+ create-release:
+ permissions:
+ contents: write
+ needs: [read-version, build-image]
+ runs-on: ubuntu-latest
+ steps:
+ ...🧰 Tools🪛 zizmor (1.26.1)[error] 12-12: overly broad permissions (excessive-permissions): contents: write is overly broad at the workflow level (excessive-permissions) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||
| read-version: | ||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||
| outputs: | ||||||||||||||||||||||||||||||
| version: ${{ steps.parse.outputs.version }} | ||||||||||||||||||||||||||||||
| major: ${{ steps.parse.outputs.major }} | ||||||||||||||||||||||||||||||
| minor: ${{ steps.parse.outputs.minor }} | ||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| ref: ${{ inputs.release-branch }} | ||||||||||||||||||||||||||||||
|
Comment on lines
+22
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major 🧩 Analysis chain🏁 Script executed: cat -n .github/workflows/release.yamlRepository: Kuadrant/authorino Length of output: 4881 Pin GitHub Actions to commit SHAs instead of mutable version tags. Using This applies to lines 22, 60, 65, 82, and 112 in this workflow file. 🧰 Tools🪛 zizmor (1.26.1)[warning] 22-24: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) [error] 22-22: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Install yq | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| sudo wget -qO /usr/local/bin/yq \ | ||||||||||||||||||||||||||||||
| https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 | ||||||||||||||||||||||||||||||
| sudo chmod +x /usr/local/bin/yq | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Parse version from release.yaml | ||||||||||||||||||||||||||||||
| id: parse | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| chmod +x .github/scripts/parse-version.sh | ||||||||||||||||||||||||||||||
| .github/scripts/parse-version.sh | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Validate branch matches version | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| EXPECTED_BRANCH="release-${{ steps.parse.outputs.major }}.${{ steps.parse.outputs.minor }}" | ||||||||||||||||||||||||||||||
| if [[ "${{ inputs.release-branch }}" != "$EXPECTED_BRANCH" ]]; then | ||||||||||||||||||||||||||||||
| echo "::error::Branch '${{ inputs.release-branch }}' does not match version ${{ steps.parse.outputs.version }} (expected branch: $EXPECTED_BRANCH)" | ||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major 🧩 Analysis chain🏁 Script executed: # First, locate and examine the release.yaml file
git ls-files | grep -E 'release\.yaml|release\.yml'Repository: Kuadrant/authorino Length of output: 235 🏁 Script executed: # Check the content around lines 38-43 of the release.yaml file
cat -n .github/workflows/release.yaml | sed -n '30,50p'Repository: Kuadrant/authorino Length of output: 1127 🌐 Web query:
💡 Result: The primary risk of context interpolation in GitHub Actions arises because workflow expressions (the Citations:
🏁 Script executed: # Check the workflow trigger and input definitions
cat -n .github/workflows/release.yaml | sed -n '1,30p'Repository: Kuadrant/authorino Length of output: 1092 Pass Line 41–42 directly interpolates the workflow dispatch input into a bash script, which allows shell command injection if the input contains metacharacters. GitHub Actions evaluates Suggested fix - name: Validate branch matches version
+ env:
+ INPUT_RELEASE_BRANCH: ${{ inputs.release-branch }}
run: |
EXPECTED_BRANCH="release-${{ steps.parse.outputs.major }}.${{ steps.parse.outputs.minor }}"
- if [[ "${{ inputs.release-branch }}" != "$EXPECTED_BRANCH" ]]; then
- echo "::error::Branch '${{ inputs.release-branch }}' does not match version ${{ steps.parse.outputs.version }} (expected branch: $EXPECTED_BRANCH)"
+ if [[ "$INPUT_RELEASE_BRANCH" != "$EXPECTED_BRANCH" ]]; then
+ echo "::error::Branch '$INPUT_RELEASE_BRANCH' does not match version ${{ steps.parse.outputs.version }} (expected branch: $EXPECTED_BRANCH)"
exit 1
fi🧰 Tools🪛 zizmor (1.26.1)[info] 40-40: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 40-40: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [error] 41-41: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [error] 42-42: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 42-42: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Check for existing release | ||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| VERSION="${{ steps.parse.outputs.version }}" | ||||||||||||||||||||||||||||||
| if gh release view "v${VERSION}" &>/dev/null; then | ||||||||||||||||||||||||||||||
| echo "::error::GitHub Release v${VERSION} already exists" | ||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| smoke-tests: | ||||||||||||||||||||||||||||||
| needs: read-version | ||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| ref: ${{ inputs.release-branch }} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Set up Go | ||||||||||||||||||||||||||||||
| uses: actions/setup-go@v5 | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| go-version-file: go.mod | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Lint | ||||||||||||||||||||||||||||||
| run: make lint | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Unit tests | ||||||||||||||||||||||||||||||
| run: make test | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: CEL validation tests | ||||||||||||||||||||||||||||||
| run: make test-cel | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| tag: | ||||||||||||||||||||||||||||||
| needs: [read-version, smoke-tests] | ||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| ref: ${{ inputs.release-branch }} | ||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Create and push tag | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| VERSION="${{ needs.read-version.outputs.version }}" | ||||||||||||||||||||||||||||||
| TAG="v${VERSION}" | ||||||||||||||||||||||||||||||
| if git rev-parse "$TAG" >/dev/null 2>&1; then | ||||||||||||||||||||||||||||||
| echo "::error::Tag $TAG already exists" | ||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
Comment on lines
+91
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win Make tag creation idempotent for safe reruns. If a previous run pushed the tag but failed later, reruns will always fail here and block recovery. Treat “tag already exists at HEAD” as success. Suggested fix if git rev-parse "$TAG" >/dev/null 2>&1; then
- echo "::error::Tag $TAG already exists"
- exit 1
+ TAG_SHA="$(git rev-list -n1 "$TAG")"
+ HEAD_SHA="$(git rev-parse HEAD)"
+ if [[ "$TAG_SHA" != "$HEAD_SHA" ]]; then
+ echo "::error::Tag $TAG already exists and points to $TAG_SHA, not $HEAD_SHA"
+ exit 1
+ fi
+ echo "Tag $TAG already exists at HEAD; continuing"
+ exit 0
fi📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
| git config user.name "github-actions[bot]" | ||||||||||||||||||||||||||||||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||||||||||||||||||||||||||||||
| git tag -a "$TAG" -m "Release $TAG" | ||||||||||||||||||||||||||||||
| git push origin "$TAG" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| build-image: | ||||||||||||||||||||||||||||||
| needs: [read-version, tag] | ||||||||||||||||||||||||||||||
| uses: ./.github/workflows/build-images.yaml | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| version: ${{ needs.read-version.outputs.version }} | ||||||||||||||||||||||||||||||
| ref: v${{ needs.read-version.outputs.version }} | ||||||||||||||||||||||||||||||
| secrets: inherit | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| create-release: | ||||||||||||||||||||||||||||||
| needs: [read-version, build-image] | ||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||
| ref: ${{ inputs.release-branch }} | ||||||||||||||||||||||||||||||
| fetch-depth: 0 | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| - name: Create GitHub release | ||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||
| VERSION="${{ needs.read-version.outputs.version }}" | ||||||||||||||||||||||||||||||
| TAG="v${VERSION}" | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| PREV_TAG=$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || echo "") | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| NOTES_ARGS="--generate-notes" | ||||||||||||||||||||||||||||||
| if [[ -n "$PREV_TAG" ]]; then | ||||||||||||||||||||||||||||||
| NOTES_ARGS="$NOTES_ARGS --notes-start-tag $PREV_TAG" | ||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| gh release create "$TAG" \ | ||||||||||||||||||||||||||||||
| --title "Release $TAG" \ | ||||||||||||||||||||||||||||||
| $NOTES_ARGS | ||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
Repository: Kuadrant/authorino
Length of output: 197
🏁 Script executed:
Repository: Kuadrant/authorino
Length of output: 1386
🏁 Script executed:
Repository: Kuadrant/authorino
Length of output: 435
🏁 Script executed:
Repository: Kuadrant/authorino
Length of output: 241
🌐 Web query:
yq key quoting hyphenated keys bracket notation syntax💡 Result:
To access keys containing hyphens in yq, you must use bracket notation with quoted strings [1][2]. Because hyphenated keys can be misinterpreted by the parser as subtraction operations, wrapping the key name in quotes (either double or single) is necessary to ensure it is treated as a literal string [1][2]. The standard syntax for accessing such a key is: yq '.["your-hyphenated-key"]' file.yaml Alternatively, you can use the syntax: yq '."your-hyphenated-key"' file.yaml It is critical to use shell-level quoting (the outer single quotes) to prevent your shell from interpreting the brackets or quotes before they are passed to yq [1]. Common pitfalls: 1. Shell Interpretation: If you do not wrap the entire expression in single quotes (e.g., yq.["key-name"]), your shell may attempt to interpret the brackets or quotes, leading to errors. 2. Operator Confusion: If you omit quotes around the key name, yq may treat the hyphen as a subtraction operator rather than a character in the key name [1]. 3. Leading Dashes: If the key name itself starts with a hyphen, you may also need to use the flag terminator (--) to stop the command from misinterpreting the key as a command-line flag [3].
Citations:
🌐 Web query:
yq .dependencies.key-name vs .dependencies["key-name"] parsing difference💡 Result:
In yq, the primary difference between dot notation (e.g.,.dependencies.key-name) and bracket notation (e.g.,.dependencies["key-name"]) is how they handle key names containing special characters, such as dots, hyphens, or spaces [1][2][3]. Dot notation is designed for simple, alphanumeric key names [4]. When a key contains special characters like a period, hyphen, or space, yq may misinterpret these characters as part of the expression's syntax—for example, treating a dot as a nested object separator rather than part of the key name [2][5][3]. Bracket notation with quotes (e.g.,.dependencies["key-name"]) acts as a robust mechanism to treat the contents within the brackets as a literal string [1][3]. This allows you to access keys that would otherwise be syntactically ambiguous or invalid in dot notation [2][6]. Key takeaways: 1. Dot notation: Suitable for standard, simple key names without special characters [4]. It cannot correctly reference keys containing dots (e.g.,.a.b.c interprets b.c as a nested structure) or other reserved symbols [2][5]. 2. Bracket notation: Required for keys containing dots, spaces, or leading dashes [1][2][3][7]. It is generally safer to use bracket notation whenever you are uncertain if a key name might conflict with yq expression syntax [6]. 3. Shell considerations: When using bracket notation in a terminal, it is important to wrap the entire expression in single quotes (e.g., '.dependencies["key-name"]') to prevent the shell from interpreting the double quotes or brackets prematurely [2][5][8]. For example, if you have a key named b.c, you must use.["b.c"] or."b.c" to access it, as.b.c would attempt to look for a key named b containing a sub-key named c [2][5].
Citations:
🏁 Script executed:
Repository: Kuadrant/authorino
Length of output: 186
🏁 Script executed:
Repository: Kuadrant/authorino
Length of output: 218
Use bracket notation with quoted keys when querying yq for dynamic dependency names.
Line 22 currently builds
.dependencies.${dep}using dot notation, which fails when dependency names contain hyphens. The yq parser misinterprets hyphens as subtraction operators rather than literal characters. This causes dependency version checks to fail silently or be skipped entirely for dependencies likemy-service.🔧 Proposed fix
🤖 Prompt for AI Agents