Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
4 changes: 2 additions & 2 deletions .devcontainer/post-create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ echo "Configuring pnpm store directory..."
pnpm config set store-dir /tmp/.pnpm-store

# Install the binary form of golangci-lint into the Go bin directory (on PATH in
# the dev container). Pinned version + checksums live in build/tools.mk.
# the dev container). Pinned version + checksums live in build/tools.yaml.
echo "Installing golangci-lint..."
GOLANGCI_LINT_INSTALL_DIR="$(go env GOPATH)/bin" make install-golangci-lint

# Install the binary form of shellcheck into the Go bin directory (on PATH in the
# dev container) so 'make lint-shell' works out of the box. Pinned version +
# checksums live in build/tools.mk.
# checksums live in build/tools.yaml.
echo "Installing shellcheck..."
SHELLCHECK_INSTALL_DIR="$(go env GOPATH)/bin" make install-shellcheck

Expand Down
2 changes: 1 addition & 1 deletion .github/actions/create-kind-cluster/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ runs:
using: composite
steps:
- name: Install KinD
# Installs the version pinned in build/tools.mk (KIND_VERSION) and adds the
# Installs the version pinned in build/tools.yaml (KIND_VERSION) and adds the
# install dir to the job PATH, so the cluster-create steps below find kind.
shell: bash
run: make install-kind
Expand Down
79 changes: 79 additions & 0 deletions .github/scripts/update-tools-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash

# ------------------------------------------------------------
# Copyright 2026 The Radius Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------

set -euo pipefail

readonly REPO_ROOT="${REPO_ROOT:-$(git rev-parse --show-toplevel)}"
readonly PR_BASE="${PR_BASE:-main}"

require_environment() {
local name
for name in GH_TOKEN GIT_USER_EMAIL GIT_USER_NAME PR_BRANCH PR_TITLE; do
if [[ -z "${!name:-}" ]]; then
echo "Error: ${name} is required" >&2
return 1
fi
done
}

pull_request_body() {
cat <<'EOF'
This automated PR refreshes the pinned command-line tool versions and SHA-256
checksums from the release sources declared in `build/tools.yaml`.

`build/tools.generated.mk` is generated from the manifest and committed with
it. Bicep remains intentionally held at its compatibility-pinned version until
local `br:localhost` functional tests support a newer release.
EOF
}

# The workflow checks out only the base branch, so there is no remote-tracking
# ref to lease against. Read the destination SHA from the remote instead; an
# empty value leases on the branch not existing yet.
push_branch() {
local expected
expected="$(
git ls-remote origin "refs/heads/${PR_BRANCH}" | awk '{print $1}'
)"
git push --force-with-lease="refs/heads/${PR_BRANCH}:${expected}" \
origin "HEAD:${PR_BRANCH}"
}

require_environment
cd "${REPO_ROOT}"

git config user.name "${GIT_USER_NAME}"
git config user.email "${GIT_USER_EMAIL}"
git checkout -B "${PR_BRANCH}"
git add -A
git commit --signoff -m "${PR_TITLE}"
gh auth setup-git
push_branch

existing_pr="$(
gh pr list --state open --head "${PR_BRANCH}" \
--json number --jq '.[0].number'
)"
body="$(pull_request_body)"
if [[ -n "${existing_pr}" ]]; then
gh pr edit "${existing_pr}" --title "${PR_TITLE}" --body "${body}"
echo "Updated PR #${existing_pr}"
else
gh pr create --base "${PR_BASE}" --head "${PR_BRANCH}" \
--title "${PR_TITLE}" --body "${body}"
fi
116 changes: 116 additions & 0 deletions .github/scripts/update-tools-pr_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/bin/bash

# ------------------------------------------------------------
# Copyright 2026 The Radius Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_DIR
TEST_ROOT="$(mktemp -d)"
readonly TEST_ROOT
trap 'rm -rf "${TEST_ROOT}"' EXIT

fail() {
echo "FAIL: $*" >&2
exit 1
}

assert_contains() {
local actual="$1"
local expected="$2"
[[ "${actual}" == *"${expected}"* ]] ||
fail "expected '${actual}' to contain '${expected}'"
}

readonly REPOSITORY="${TEST_ROOT}/repository"
readonly REMOTE="${TEST_ROOT}/remote.git"
readonly SEED="${TEST_ROOT}/seed"
readonly FAKE_BIN="${TEST_ROOT}/bin"
readonly GH_LOG_PATH="${TEST_ROOT}/gh.log"

git init -q --bare "${REMOTE}"
git init -q -b main "${SEED}"
git -C "${SEED}" config user.name "Test User"
Comment thread
lakshmimsft marked this conversation as resolved.
git -C "${SEED}" config user.email "test@example.com"
echo "original" >"${SEED}/tools.yaml"
git -C "${SEED}" add tools.yaml
git -C "${SEED}" commit -q -m "initial"
git -C "${SEED}" remote add origin "${REMOTE}"
git -C "${SEED}" push -q origin main

# The workflow checks out the base branch only, so the automation branch never
# gains a remote-tracking ref. Mirror that here or the pushes below lease
# against a ref that CI does not have.
git clone -q --single-branch --branch main "${REMOTE}" "${REPOSITORY}"

mkdir -p "${FAKE_BIN}"
cat >"${FAKE_BIN}/gh" <<'EOF'
Comment thread
DariuszPorowski marked this conversation as resolved.
#!/bin/bash
set -euo pipefail
printf '%s\n' "$*" >>"${GH_LOG}"
if [[ "$1 $2" == "pr list" ]]; then
printf '%s\n' "${EXISTING_PR:-}"
fi
EOF
chmod +x "${FAKE_BIN}/gh"

run_script() {
local existing_pr="$1"
PATH="${FAKE_BIN}:${PATH}" \
REPO_ROOT="${REPOSITORY}" \
GH_LOG="${GH_LOG_PATH}" \
EXISTING_PR="${existing_pr}" \
GH_TOKEN="test-token" \
GIT_USER_EMAIL="automation@example.com" \
GIT_USER_NAME="Automation Bot" \
PR_BRANCH="automation/update-tools" \
PR_TITLE="chore: update pinned tool versions" \
bash "${SCRIPT_DIR}/update-tools-pr.sh" >/dev/null
}

echo "first update" >>"${REPOSITORY}/tools.yaml"
run_script ""

commit_message="$(
git --git-dir="${REMOTE}" log -1 --format=%B \
refs/heads/automation/update-tools
)"
assert_contains "${commit_message}" "chore: update pinned tool versions"
assert_contains \
"${commit_message}" \
"Signed-off-by: Automation Bot <automation@example.com>"
assert_contains "$(cat "${GH_LOG_PATH}")" "pr create"

if git -C "${REPOSITORY}" show-ref --quiet \
refs/remotes/origin/automation/update-tools; then
fail "fixture drifted from CI: the automation branch is now tracked"
fi

before="$(
git --git-dir="${REMOTE}" rev-parse refs/heads/automation/update-tools
)"
git -C "${REPOSITORY}" checkout -q main
echo "second update" >>"${REPOSITORY}/tools.yaml"
run_script "42"
after="$(
git --git-dir="${REMOTE}" rev-parse refs/heads/automation/update-tools
)"
assert_contains "$(cat "${GH_LOG_PATH}")" "pr edit 42"
[[ "${before}" != "${after}" ]] ||
fail "expected the remote automation branch to be updated"

echo "update-tools-pr tests passed"
4 changes: 2 additions & 2 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ jobs:

- name: Install oras
if: needs.changes.outputs.only_changed != 'true'
# Version pinned in build/tools.mk (ORAS_VERSION).
# Version pinned in build/tools.yaml (ORAS_VERSION).
run: make install-oras

- name: Push latest rad cli binary to GHCR (unix-like)
Expand Down Expand Up @@ -328,7 +328,7 @@ jobs:
persist-credentials: false

- name: Install helm
# Version pinned in build/tools.mk (HELM_VERSION).
# Version pinned in build/tools.yaml (HELM_VERSION).
run: make install-helm

- name: Setup Python
Expand Down
30 changes: 18 additions & 12 deletions .github/workflows/copilot-setup-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# functional-test-noncloud.yaml). Language runtime versions are read from the
# repo's version files (go.mod, .node-version, .python-version, .terraform-version)
# so a version bump flows here automatically; CLI tool versions and checksums are
# pinned in build/tools.mk and installed via the shared `make install-<tool>`
# pinned in build/tools.yaml and installed via the shared `make install-<tool>`
# targets. Versions are NOT declared in a workflow-level `env:`
# block because the Copilot coding agent replays these steps in a harness that
# does not provide that context.
Expand All @@ -41,15 +41,21 @@ on:
- .node-version
- .python-version
- .terraform-version
- build/tools.yaml
- build/tools.mk
- cmd/tool-updater/**
- internal/tooling/**
- build/scripts/install-*.sh
pull_request:
paths:
- .github/workflows/copilot-setup-steps.yml
- .node-version
- .python-version
- .terraform-version
- build/tools.yaml
- build/tools.mk
- cmd/tool-updater/**
- internal/tooling/**
- build/scripts/install-*.sh

permissions: {}
Expand All @@ -64,7 +70,7 @@ permissions: {}
# See: https://docs.github.com/en/copilot/how-tos/use-copilot-agents/coding-agent/customize-the-agent-environment
# Language runtime versions read from repo version files (go.mod, .node-version,
# .python-version, .terraform-version) still work because the steps read the files
# directly; CLI tool versions come from build/tools.mk via `make install-<tool>`.
# directly; CLI tool versions come from build/tools.yaml via `make install-<tool>`.

jobs:
# The job MUST be named `copilot-setup-steps` for the Copilot coding agent to
Expand Down Expand Up @@ -103,11 +109,11 @@ jobs:
python-version-file: .python-version

- name: Install helm
# Version pinned in build/tools.mk (HELM_VERSION).
# Version pinned in build/tools.yaml (HELM_VERSION).
run: make install-helm

- name: Install kubectl
# Version pinned in build/tools.mk (KUBECTL_VERSION).
# Version pinned in build/tools.yaml (KUBECTL_VERSION).
run: make install-kubectl

- name: Install pnpm and TypeSpec tooling
Expand Down Expand Up @@ -136,14 +142,14 @@ jobs:
cspell --version

- name: Install golangci-lint
# Pinned version + checksums live in build/tools.mk (GOLANGCI_LINT_VERSION).
# Pinned version + checksums live in build/tools.yaml (GOLANGCI_LINT_VERSION).
run: make install-golangci-lint

- name: Install Delve (dlv)
# controller-gen, mockgen, and gotestsum are managed as Go tool dependencies
# (the 'tool' directives in go.mod) and run via `go tool`, so they need no
# separate install. dlv (Delve) is used by the process-debugging workflow
# (make debug-*). Version pinned in build/tools.mk (DLV_VERSION).
# (make debug-*). Version pinned in build/tools.yaml (DLV_VERSION).
run: make install-dlv

- name: Install yq
Expand All @@ -152,31 +158,31 @@ jobs:

- name: Install KinD
# Lets the agent create a local Kubernetes cluster for integration and
# functional tests. Version pinned in build/tools.mk (KIND_VERSION).
# functional tests. Version pinned in build/tools.yaml (KIND_VERSION).
run: make install-kind

- name: Install k3d
# Used by the local debug environment (make debug-start) to create a
# lightweight Kubernetes cluster. Version pinned in build/tools.mk (K3D_VERSION).
# lightweight Kubernetes cluster. Version pinned in build/tools.yaml (K3D_VERSION).
run: make install-k3d

- name: Install stern
# Multi-pod log tailing for debugging Kubernetes output across the
# radius-system components. Version pinned in build/tools.mk (STERN_VERSION).
# radius-system components. Version pinned in build/tools.yaml (STERN_VERSION).
run: make install-stern

- name: Install Dapr CLI
# Version pinned in build/tools.mk (DAPR_VERSION).
# Version pinned in build/tools.yaml (DAPR_VERSION).
run: make install-dapr

- name: Install Terraform
# Version defaults to .terraform-version (overridable via TERRAFORM_VERSION)
# and is compiled into the rad binary; checksums pinned in build/tools.mk.
# and is compiled into the rad binary; checksums pinned in build/tools.yaml.
run: make install-terraform

- name: Install Bicep CLI
# Required by Bicep type publishing (make publish-bicep-extension) and
# rad bicep flows. Pinned version + checksum live in build/tools.mk.
# rad bicep flows. Pinned version + checksum live in build/tools.yaml.
run: make install-bicep

- name: Install PostgreSQL client
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/functional-test-cloud.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ jobs:
make generate-bicep-types VERSION="${BICEP_TYPES_VERSION}"

- name: Install bicep CLI
# Pinned version + checksum live in build/tools.mk (previously installed
# Pinned version + checksum live in build/tools.yaml (previously installed
# the unpinned 'latest', which could pull v0.43+).
run: make install-bicep

Expand Down Expand Up @@ -745,7 +745,7 @@ jobs:
AZURE_SUBSCRIPTIONID_TESTS: ${{ secrets.AZURE_SUBSCRIPTIONID_TESTS }}

- name: Install helm
# Version pinned in build/tools.mk (HELM_VERSION).
# Version pinned in build/tools.yaml (HELM_VERSION).
run: make install-helm

# The role-to-assume is the role that the github action will assume to execute aws commands and
Expand All @@ -758,7 +758,7 @@ jobs:
aws-region: ${{ env.AWS_REGION }}

- name: Install KinD
# Installs the version pinned in build/tools.mk (KIND_VERSION) and adds
# Installs the version pinned in build/tools.yaml (KIND_VERSION) and adds
# the install dir to the job PATH for the cluster-create step below.
run: make install-kind

Expand Down
Loading
Loading