From 138b39bfcb7ddba3b7fd6e21be880531722fc4ab Mon Sep 17 00:00:00 2001 From: Nikola Jokic Date: Wed, 19 Nov 2025 16:25:58 +0100 Subject: [PATCH 1/8] Create e2e test suite (#3136) Co-authored-by: Bassem Dghaidi <568794+Link-@users.noreply.github.com> --- .github/workflows/gha-e2e-tests.yaml | 224 ++++++++++++++++++ Makefile | 6 +- hack/e2e-test.sh | 92 +++++++ .../anonymous-proxy-setup.squid.yaml | 31 +++ .../anonymous-proxy-setup.test.sh | 87 +++++++ .../auth-proxy-setup.squid.yaml | 31 +++ .../auth-proxy-setup.test.sh | 102 ++++++++ test/actions.github.com/default-setup.test.sh | 73 ++++++ .../dind-mode-setup.test.sh | 74 ++++++ test/actions.github.com/envrc.example | 3 + test/actions.github.com/helper.sh | 193 +++++++++++++++ .../init-with-min-runners.test.sh | 94 ++++++++ .../kubernetes-mode-setup.test.sh | 81 +++++++ .../self-signed-ca-setup.mitm.yaml | 29 +++ .../self-signed-ca-setup.test.sh | 148 ++++++++++++ .../single-namespace-setup.test.sh | 74 ++++++ .../update-strategy.test.sh | 146 ++++++++++++ 17 files changed, 1486 insertions(+), 2 deletions(-) create mode 100755 hack/e2e-test.sh create mode 100644 test/actions.github.com/anonymous-proxy-setup.squid.yaml create mode 100755 test/actions.github.com/anonymous-proxy-setup.test.sh create mode 100644 test/actions.github.com/auth-proxy-setup.squid.yaml create mode 100755 test/actions.github.com/auth-proxy-setup.test.sh create mode 100755 test/actions.github.com/default-setup.test.sh create mode 100755 test/actions.github.com/dind-mode-setup.test.sh create mode 100644 test/actions.github.com/envrc.example create mode 100644 test/actions.github.com/helper.sh create mode 100755 test/actions.github.com/init-with-min-runners.test.sh create mode 100755 test/actions.github.com/kubernetes-mode-setup.test.sh create mode 100644 test/actions.github.com/self-signed-ca-setup.mitm.yaml create mode 100755 test/actions.github.com/self-signed-ca-setup.test.sh create mode 100755 test/actions.github.com/single-namespace-setup.test.sh create mode 100755 test/actions.github.com/update-strategy.test.sh diff --git a/.github/workflows/gha-e2e-tests.yaml b/.github/workflows/gha-e2e-tests.yaml index bbf14631..f35c7a2e 100644 --- a/.github/workflows/gha-e2e-tests.yaml +++ b/.github/workflows/gha-e2e-tests.yaml @@ -26,6 +26,30 @@ concurrency: cancel-in-progress: true jobs: + default-setup-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run default setup test + run: hack/e2e-test.sh default-setup + shell: bash + default-setup: runs-on: ubuntu-latest timeout-minutes: 20 @@ -117,6 +141,31 @@ jobs: arc-namespace: "arc-runners" arc-controller-namespace: "arc-systems" + single-namespace-setup-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run single namespace setup test + run: hack/e2e-test.sh single-namespace-setup + shell: bash + single-namespace-setup: runs-on: ubuntu-latest timeout-minutes: 20 @@ -210,6 +259,31 @@ jobs: arc-namespace: "arc-runners" arc-controller-namespace: "arc-systems" + dind-mode-setup-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run dind mode setup test + run: hack/e2e-test.sh dind-mode-setup + shell: bash + dind-mode-setup: runs-on: ubuntu-latest timeout-minutes: 20 @@ -302,6 +376,31 @@ jobs: arc-namespace: "arc-runners" arc-controller-namespace: "arc-systems" + kubernetes-mode-setup-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run kubernetes mode setup test + run: hack/e2e-test.sh kubernetes-mode-setup + shell: bash + kubernetes-mode-setup: runs-on: ubuntu-latest timeout-minutes: 20 @@ -403,6 +502,31 @@ jobs: arc-namespace: "arc-runners" arc-controller-namespace: "arc-systems" + auth-proxy-setup-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run single namespace setup test + run: hack/e2e-test.sh single-namespace-setup + shell: bash + auth-proxy-setup: runs-on: ubuntu-latest timeout-minutes: 20 @@ -506,6 +630,31 @@ jobs: arc-namespace: "arc-runners" arc-controller-namespace: "arc-systems" + anonymous-proxy-setup-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run anonymous proxy setup test + run: hack/e2e-test.sh anonymous-proxy-setup + shell: bash + anonymous-proxy-setup: runs-on: ubuntu-latest timeout-minutes: 20 @@ -603,6 +752,31 @@ jobs: arc-namespace: "arc-runners" arc-controller-namespace: "arc-systems" + self-signed-ca-setup-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run self signed CA setup test + run: hack/e2e-test.sh self-signed-ca-setup + shell: bash + self-signed-ca-setup: runs-on: ubuntu-latest timeout-minutes: 20 @@ -725,6 +899,31 @@ jobs: arc-namespace: "arc-runners" arc-controller-namespace: "arc-systems" + update-strategy-tests-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run update strategy test + run: hack/e2e-test.sh update-strategy + shell: bash + update-strategy-tests: runs-on: ubuntu-latest timeout-minutes: 20 @@ -897,6 +1096,31 @@ jobs: kubectl wait --timeout=10s --for=delete AutoScalingRunnerSet -n "${{ steps.install_arc.outputs.ARC_NAME }}" -l app.kubernetes.io/instance="${{ steps.install_arc.outputs.ARC_NAME }}" kubectl logs deployment/arc-gha-rs-controller -n "arc-systems" + init-with-min-runners-v2: + runs-on: ubuntu-latest + timeout-minutes: 20 + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id + env: + TARGET_ORG: ${{ env.TARGET_ORG }} + TARGET_REPO: ${{ env.TARGET_REPO }} + + steps: + - uses: actions/checkout@v5 + with: + ref: ${{github.head_ref}} + + - name: Get configure token + id: config-token + uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 + with: + application_id: ${{ secrets.E2E_TESTS_ACCESS_APP_ID }} + application_private_key: ${{ secrets.E2E_TESTS_ACCESS_PK }} + organization: ${{ env.TARGET_ORG }} + + - name: Run init with min runners test + run: hack/e2e-test.sh init-with-min-runners + shell: bash + init-with-min-runners: runs-on: ubuntu-latest timeout-minutes: 20 diff --git a/Makefile b/Makefile index ed96d07a..c7ecf843 100644 --- a/Makefile +++ b/Makefile @@ -210,8 +210,6 @@ docker-buildx: docker buildx create --platform ${PLATFORMS} --name container-builder --use;\ fi docker buildx build --platform ${PLATFORMS} \ - --build-arg RUNNER_VERSION=${RUNNER_VERSION} \ - --build-arg DOCKER_VERSION=${DOCKER_VERSION} \ --build-arg VERSION=${VERSION} \ --build-arg COMMIT_SHA=${COMMIT_SHA} \ -t "${DOCKER_IMAGE_NAME}:${VERSION}" \ @@ -297,6 +295,10 @@ acceptance/runner/startup: e2e: go test -count=1 -v -timeout 600s -run '^TestE2E$$' ./test/e2e +.PHONY: gha-e2e +gha-e2e: + bash hack/e2e-test.sh + # Upload release file to GitHub. github-release: release ghr ${VERSION} release/ diff --git a/hack/e2e-test.sh b/hack/e2e-test.sh new file mode 100755 index 00000000..d532662e --- /dev/null +++ b/hack/e2e-test.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +DIR="$(dirname "${BASH_SOURCE[0]}")" + +DIR="$(realpath "${DIR}")" + +TEST_DIR="$(realpath "${DIR}/../test/actions.github.com")" + +export PLATFORMS="linux/amd64" + +TARGETS=() + +function set_targets() { + local cases="$(find "${TEST_DIR}" -name '*.test.sh' | sed "s#^${TEST_DIR}/##g" )" + + mapfile -t TARGETS < <(echo "${cases}") + + echo $TARGETS +} + +function env_test() { + if [[ -z "${GITHUB_TOKEN}" ]]; then + echo "Error: GITHUB_TOKEN is not set" + exit 1 + fi + + if [[ -z "${TARGET_ORG}" ]]; then + echo "Error: TARGET_ORG is not set" + exit 1 + fi + + if [[ -z "${TARGET_REPO}" ]]; then + echo "Error: TARGET_REPO is not set" + exit 1 + fi +} + +function usage() { + echo "Usage: $0 [test_name]" + echo " test_name: the name of the test to run" + echo " if not specified, all tests will be run" + echo " test_name should be the name of the test file without the .test.sh suffix" + echo "" + exit 1 +} + +function main() { + local failed=() + + env_test + + if [[ -z "${1}" ]]; then + echo "Running all tests" + set_targets + elif [[ -f "${TEST_DIR}/${1}.test.sh" ]]; then + echo "Running test ${1}" + TARGETS=("${1}.test.sh") + else + usage + fi + + for target in "${TARGETS[@]}"; do + echo "============================================================" + test="${TEST_DIR}/${target}" + if [[ ! -x "${test}" ]]; then + echo "Error: test ${test} is not executable or not found" + failed+=("${test}") + continue + fi + + echo "Running test ${target}" + if ! "${test}"; then + failed+=("${target}") + echo "---------------------------------" + echo "FAILED: ${target}" + else + echo "---------------------------------" + echo "PASSED: ${target}" + fi + echo "============================================================" + done + + if [[ "${#failed[@]}" -gt 0 ]]; then + echo "Failed tests:" + for fail in "${failed[@]}"; do + echo " ${fail}" + done + exit 1 + fi +} + +main $@ diff --git a/test/actions.github.com/anonymous-proxy-setup.squid.yaml b/test/actions.github.com/anonymous-proxy-setup.squid.yaml new file mode 100644 index 00000000..b56bd181 --- /dev/null +++ b/test/actions.github.com/anonymous-proxy-setup.squid.yaml @@ -0,0 +1,31 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: squid +spec: + replicas: 1 + selector: + matchLabels: + app: squid + template: + metadata: + labels: + app: squid + spec: + containers: + - name: squid + image: ubuntu/squid:latest + ports: + - containerPort: 3128 +--- +apiVersion: v1 +kind: Service +metadata: + name: squid +spec: + selector: + app: squid + ports: + - protocol: TCP + port: 3128 + targetPort: 3128 diff --git a/test/actions.github.com/anonymous-proxy-setup.test.sh b/test/actions.github.com/anonymous-proxy-setup.test.sh new file mode 100755 index 00000000..fb79fb10 --- /dev/null +++ b/test/actions.github.com/anonymous-proxy-setup.test.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" + +SCALE_SET_NAME="anonymous-proxy-$(date +'%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +function install_arc() { + echo "Creating namespace ${ARC_NAMESPACE}" + kubectl create namespace "${SCALE_SET_NAMESPACE}" + + echo "Installing ARC" + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_squid() { + echo "Starting squid-proxy" + kubectl apply -f "${DIR}/anonymous-proxy-setup.squid.yaml" +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" + + echo helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + --set proxy.https.url="http://squid.default.svc.cluster.local:3128" \ + --set "proxy.noProxy[0]=10.96.0.1:443" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function main() { + local failed=() + + build_image + create_cluster + + install_arc + install_squid + + install_scale_set || { + echo "Scale set installation failed" + NAMESPACE="${ARC_NAMESPACE}" log_arc + delete_cluster + exit 1 + } + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/auth-proxy-setup.squid.yaml b/test/actions.github.com/auth-proxy-setup.squid.yaml new file mode 100644 index 00000000..7ba99495 --- /dev/null +++ b/test/actions.github.com/auth-proxy-setup.squid.yaml @@ -0,0 +1,31 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: squid +spec: + replicas: 1 + selector: + matchLabels: + app: squid + template: + metadata: + labels: + app: squid + spec: + containers: + - name: squid + image: huangtingluo/squid-proxy:latest + ports: + - containerPort: 3128 +--- +apiVersion: v1 +kind: Service +metadata: + name: squid +spec: + selector: + app: squid + ports: + - protocol: TCP + port: 3128 + targetPort: 3128 diff --git a/test/actions.github.com/auth-proxy-setup.test.sh b/test/actions.github.com/auth-proxy-setup.test.sh new file mode 100755 index 00000000..d13054fd --- /dev/null +++ b/test/actions.github.com/auth-proxy-setup.test.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" + +SCALE_SET_NAME="default-$(date +'%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +function install_arc() { + echo "Install openebs/dynamic-localpv-provisioner" + helm repo add openebs https://openebs.github.io/charts + helm repo update + helm install openebs openebs/openebs -n openebs --create-namespace + + echo "Creating namespace ${ARC_NAMESPACE}" + kubectl create namespace "${SCALE_SET_NAMESPACE}" + + echo "Installing ARC" + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_squid() { + echo "Starting squid-proxy" + kubectl apply -f "${DIR}/auth-proxy-setup.squid.yaml" + + echo "Creating scale set namespace" + kubectl create namespace "${SCALE_SET_NAMESPACE}" || true + + echo "Creating squid proxy secret" + kubectl create secret generic proxy-auth \ + --namespace=arc-runners \ + --from-literal=username=github \ + --from-literal=password='actions' +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + --set proxy.https.url="http://squid.default.svc.cluster.local:3128" \ + --set proxy.https.credentialSecretRef="proxy-auth" \ + --set "proxy.noProxy[0]=10.96.0.1:443" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --version="${VERSION}" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function main() { + local failed=() + + build_image + create_cluster + + install_arc + install_squid + + install_scale_set || { + echo "Scale set installation failed" + NAMESPACE="${ARC_NAMESPACE}" log_arc + delete_cluster + exit 1 + } + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/default-setup.test.sh b/test/actions.github.com/default-setup.test.sh new file mode 100755 index 00000000..2669320b --- /dev/null +++ b/test/actions.github.com/default-setup.test.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" + +SCALE_SET_NAME="default-$(date +'%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +function install_arc() { + echo "Creating namespace ${ARC_NAMESPACE}" + kubectl create namespace "${SCALE_SET_NAMESPACE}" + + echo "Installing ARC" + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --version="${VERSION}" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function main() { + local failed=() + + build_image + create_cluster + + install_arc + install_scale_set + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/dind-mode-setup.test.sh b/test/actions.github.com/dind-mode-setup.test.sh new file mode 100755 index 00000000..2c70af76 --- /dev/null +++ b/test/actions.github.com/dind-mode-setup.test.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" + +SCALE_SET_NAME="default-$(date +'%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-dind-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +function install_arc() { + echo "Creating namespace ${ARC_NAMESPACE}" + kubectl create namespace "${SCALE_SET_NAMESPACE}" + + echo "Installing ARC" + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + --set containerMode.type="dind" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --version="${VERSION}" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function main() { + local failed=() + + build_image + create_cluster + + install_arc + install_scale_set + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/envrc.example b/test/actions.github.com/envrc.example new file mode 100644 index 00000000..5db64c18 --- /dev/null +++ b/test/actions.github.com/envrc.example @@ -0,0 +1,3 @@ +export TARGET_ORG="org" +export TARGET_REPO="repo" +export GITHUB_TOKEN="token" diff --git a/test/actions.github.com/helper.sh b/test/actions.github.com/helper.sh new file mode 100644 index 00000000..32718035 --- /dev/null +++ b/test/actions.github.com/helper.sh @@ -0,0 +1,193 @@ +#!/bin/bash + +DIR="$(dirname "${BASH_SOURCE[0]}")" + +DIR="$(realpath "${DIR}")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +export TARGET_ORG="${TARGET_ORG:-actions-runner-controller}" +export TARGET_REPO="${TARGET_REPO:-arc_e2e_test_dummy}" +export IMAGE_NAME="${IMAGE_NAME:-arc-test-image}" +export VERSION="${VERSION:-$(yq .version <"${ROOT_DIR}/charts/gha-runner-scale-set-controller/Chart.yaml")}" +export IMAGE_TAG="${VERSION}" +export IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" + +export PLATFORMS="linux/amd64" +export COMMIT_SHA="$(git rev-parse HEAD)" + +function build_image() { + echo "Building ARC image ${IMAGE}" + + cd "${ROOT_DIR}" || exit 1 + + docker buildx build --platform "${PLATFORMS}" \ + --build-arg VERSION="${VERSION}" \ + --build-arg COMMIT_SHA="${COMMIT_SHA}" \ + -t "${IMAGE}" \ + -f Dockerfile \ + . --load + + echo "Created image ${IMAGE}" + cd - || exit 1 +} + +function create_cluster() { + echo "Deleting minikube cluster if exists" + minikube delete || true + + echo "Creating minikube cluster" + minikube start --driver=docker --container-runtime=docker --wait=all + + echo "Verifying ns works" + if ! minikube ssh "nslookup github.com >/dev/null 2>&1"; then + echo "Nameserver configuration failed" + exit 1 + fi + + echo "Loading image into minikube cluster" + minikube image load "${IMAGE}" + + echo "Loading runner image into minikube cluster" + minikube image load "ghcr.io/actions/actions-runner:latest" +} + +function delete_cluster() { + echo "Deleting minikube cluster" + minikube delete +} + +function log_arc() { + echo "ARC logs" + kubectl logs -n "${NAMESPACE}" -l app.kubernetes.io/name=gha-rs-controller +} + +function wait_for_arc() { + echo "Waiting for ARC to be ready" + local count=0 + while true; do + POD_NAME=$(kubectl get pods -n "${NAMESPACE}" -l app.kubernetes.io/name=gha-rs-controller -o name) + if [ -n "$POD_NAME" ]; then + echo "Pod found: $POD_NAME" + break + fi + if [ "$count" -ge 60 ]; then + echo "Timeout waiting for controller pod with label app.kubernetes.io/name=gha-rs-controller" + return 1 + fi + sleep 1 + count=$((count + 1)) + done + + kubectl wait --timeout=30s --for=condition=ready pod -n "${NAMESPACE}" -l app.kubernetes.io/name=gha-rs-controller + kubectl get pod -n "${NAMESPACE}" + kubectl describe deployment "${NAME}" -n "${NAMESPACE}" +} + +function wait_for_scale_set() { + local count=0 + while true; do + POD_NAME=$(kubectl get pods -n "${NAMESPACE}" -l "actions.github.com/scale-set-name=${NAME}" -o name) + if [ -n "$POD_NAME" ]; then + echo "Pod found: ${POD_NAME}" + break + fi + + if [ "$count" -ge 60 ]; then + echo "Timeout waiting for listener pod with label actions.github.com/scale-set-name=${NAME}" + return 1 + fi + + sleep 1 + count=$((count + 1)) + done + kubectl wait --timeout=30s --for=condition=ready pod -n "${NAMESPACE}" -l "actions.github.com/scale-set-name=${NAME}" + kubectl get pod -n "${NAMESPACE}" -l "actions.github.com/scale-set-name=${NAME}" +} + +function cleanup_scale_set() { + helm uninstall "${INSTALLATION_NAME}" --namespace "${NAMESPACE}" --debug + + kubectl wait --timeout=40s --for=delete autoscalingrunnersets -n "${NAMESPACE}" -l app.kubernetes.io/instance="${INSTALLATION_NAME}" +} + +function install_openebs() { + echo "Install openebs/dynamic-localpv-provisioner" + helm repo add openebs https://openebs.github.io/charts + helm repo update + helm install openebs openebs/openebs --namespace openebs --create-namespace +} + +function print_results() { + local failed=("$@") + + if [[ "${#failed[@]}" -ne 0 ]]; then + echo "----------------------------------" + echo "The following tests failed:" + for test in "${failed[@]}"; do + echo " - ${test}" + done + return 1 + else + echo "----------------------------------" + echo "All tests passed!" + fi +} + +function run_workflow() { + echo "Checking if the workflow file exists" + gh workflow view -R "${TARGET_ORG}/${TARGET_REPO}" "${WORKFLOW_FILE}" || return 1 + + local queue_time="$(date -u +%FT%TZ)" + + echo "Running workflow ${WORKFLOW_FILE}" + gh workflow run -R "${TARGET_ORG}/${TARGET_REPO}" "${WORKFLOW_FILE}" --ref main -f arc_name="${SCALE_SET_NAME}" || return 1 + + echo "Waiting for run to start" + local count=0 + local run_id= + while true; do + if [[ "${count}" -ge 12 ]]; then + echo "Timeout waiting for run to start" + return 1 + fi + run_id=$(gh run list -R "${TARGET_ORG}/${TARGET_REPO}" --workflow "${WORKFLOW_FILE}" --created ">${queue_time}" --json "name,databaseId" --jq ".[] | select(.name | contains(\"${SCALE_SET_NAME}\")) | .databaseId") + echo "Run ID: ${run_id}" + if [ -n "$run_id" ]; then + echo "Run found!" + break + fi + + echo "Run not found yet, waiting 5 seconds" + sleep 5 + count=$((count + 1)) + done + + echo "Waiting for run to complete" + local code=$(gh run watch "${run_id}" -R "${TARGET_ORG}/${TARGET_REPO}" --exit-status &>/dev/null) + if [[ "${code}" -ne 0 ]]; then + echo "Run failed with exit code ${code}" + return 1 + fi + + echo "Run completed successfully" +} + +function retry() { + local retries=$1 + shift + local delay=$1 + shift + local n=1 + + until "$@"; do + if [[ $n -ge $retries ]]; then + echo "Attempt $n failed! No more retries left." + return 1 + else + echo "Attempt $n failed! Retrying in $delay seconds..." + sleep "$delay" + n=$((n + 1)) + fi + done +} diff --git a/test/actions.github.com/init-with-min-runners.test.sh b/test/actions.github.com/init-with-min-runners.test.sh new file mode 100755 index 00000000..8ca08ab9 --- /dev/null +++ b/test/actions.github.com/init-with-min-runners.test.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" || { + echo "Failed to source helper.sh" + exit 1 +} + +SCALE_SET_NAME="init-min-runners-$(date +'%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +function install_arc() { + echo "Installing ARC" + helm install arc \ + --namespace "arc-systems" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + --set flags.updateStrategy="eventual" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + --set minRunners=5 \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function assert_5_runners() { + echo "[*] Asserting 5 runners are created" + local count=0 + while true; do + pod_count=$(kubectl get pods -n arc-runners --no-headers | wc -l) + + if [[ "${pod_count}" = 5 ]]; then + echo "[*] Found 5 runners as expected" + break + fi + + if [[ "$count" -ge 30 ]]; then + echo "Timeout waiting for 5 pods to be created" + exit 1 + fi + sleep 1 + count=$((count + 1)) + done +} + +function main() { + local failed=() + + build_image + create_cluster + + install_arc + install_scale_set + + assert_5_runners || failed+=("assert_5_runners") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/kubernetes-mode-setup.test.sh b/test/actions.github.com/kubernetes-mode-setup.test.sh new file mode 100755 index 00000000..8a2dd1fe --- /dev/null +++ b/test/actions.github.com/kubernetes-mode-setup.test.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" + +SCALE_SET_NAME="kubernetes-mode-$(date +'%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-kubernetes-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +function install_arc() { + echo "Install openebs/dynamic-localpv-provisioner" + helm repo add openebs https://openebs.github.io/charts + helm repo update + helm install openebs openebs/openebs -n openebs --create-namespace + + echo "Creating namespace ${ARC_NAMESPACE}" + kubectl create namespace "${SCALE_SET_NAMESPACE}" + + echo "Installing ARC" + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + --set containerMode.type="kubernetes" \ + --set containerMode.kubernetesModeWorkVolumeClaim.accessModes={"ReadWriteOnce"} \ + --set containerMode.kubernetesModeWorkVolumeClaim.storageClassName="openebs-hostpath" \ + --set containerMode.kubernetesModeWorkVolumeClaim.resources.requests.storage="1Gi" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function main() { + local failed=() + + build_image + create_cluster + + install_arc + install_scale_set + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/self-signed-ca-setup.mitm.yaml b/test/actions.github.com/self-signed-ca-setup.mitm.yaml new file mode 100644 index 00000000..00382d6d --- /dev/null +++ b/test/actions.github.com/self-signed-ca-setup.mitm.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Pod +metadata: + name: mitmproxy + namespace: mitmproxy + labels: + app: mitmproxy +spec: + containers: + - name: mitmproxy + image: mitmproxy/mitmproxy:latest + command: ["mitmdump"] + ports: + - containerPort: 8080 + name: proxy +--- +apiVersion: v1 +kind: Service +metadata: + name: mitmproxy + namespace: mitmproxy +spec: + selector: + app: mitmproxy + ports: + - port: 8080 + targetPort: 8080 + name: proxy + diff --git a/test/actions.github.com/self-signed-ca-setup.test.sh b/test/actions.github.com/self-signed-ca-setup.test.sh new file mode 100755 index 00000000..1264433d --- /dev/null +++ b/test/actions.github.com/self-signed-ca-setup.test.sh @@ -0,0 +1,148 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" || { + echo "Failed to source helper.sh" + exit 1 +} + +TEMP_DIR=$(mktemp -d) +LOCAL_CERT_PATH="${TEMP_DIR}/mitmproxy-ca-cert.crt" +MITM_CERT_PATH="/root/.mitmproxy/mitmproxy-ca-cert.pem" + +trap 'rm -rf "$TEMP_DIR"' EXIT + +SCALE_SET_NAME="self-signed-crt-$(date '+%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +MITMPROXY_NAMESPACE="mitmproxy" +MITMPROXY_POD_NAME="mitmproxy" + +function install_arc() { + echo "Installing ARC" + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_scale_set() { + echo "Creating namespace ${SCALE_SET_NAMESPACE}" + kubectl create namespace "${SCALE_SET_NAMESPACE}" + + echo "Installing ca-cert config map" + kubectl -n "${SCALE_SET_NAMESPACE}" create configmap ca-cert \ + --from-file=mitmproxy-ca-cert.crt="${LOCAL_CERT_PATH}" + + echo "Installing scale set ${SCALE_SET_NAME}/${SCALE_SET_NAMESPACE}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + --set proxy.https.url="http://mitmproxy.mitmproxy.svc.cluster.local:8080" \ + --set "proxy.noProxy[0]=10.96.0.1:443" \ + --set "githubServerTLS.certificateFrom.configMapKeyRef.name=ca-cert" \ + --set "githubServerTLS.certificateFrom.configMapKeyRef.key=mitmproxy-ca-cert.crt" \ + --set "githubServerTLS.runnerMountPath=/usr/local/share/ca-certificates/" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function wait_for_mitmproxy_ready() { + echo "Waiting for mitmproxy pod to be ready" + + # Wait for pod to be running + if ! kubectl wait --for=condition=ready pod -n "${MITMPROXY_NAMESPACE}" "${MITMPROXY_POD_NAME}" --timeout=60s; then + echo "Timeout waiting for mitmproxy pod" + kubectl get pods -n "${MITMPROXY_NAMESPACE}" || true + kubectl describe pod -n "${MITMPROXY_NAMESPACE}" "${MITMPROXY_POD_NAME}" || true + kubectl logs -n "${MITMPROXY_NAMESPACE}" "${MITMPROXY_POD_NAME}" || true + return 1 + fi + + echo "Mitmproxy pod is ready, trying to copy the certitficate..." + + # Verify certificate exists + retry 15 1 kubectl exec -n "${MITMPROXY_NAMESPACE}" "${MITMPROXY_POD_NAME}" -- test -f "${MITM_CERT_PATH}" + + echo "Getting mitmproxy CA certificate from pod" + if ! kubectl exec -n "${MITMPROXY_NAMESPACE}" "${MITMPROXY_POD_NAME}" -- cat "${MITM_CERT_PATH}" >"${LOCAL_CERT_PATH}"; then + echo "Failed to get mitmproxy CA certificate from pod" + return 1 + fi + echo "Mitmproxy certificate generated successfully and stored to ${LOCAL_CERT_PATH}" + return 0 +} + +function run_mitmproxy() { + echo "Deploying mitmproxy to Kubernetes" + + # Create namespace + kubectl create namespace "${MITMPROXY_NAMESPACE}" || true + + # Create mitmproxy pod and service + kubectl apply -f "${DIR}/self-signed-ca-setup.mitm.yaml" + + if ! wait_for_mitmproxy_ready; then + return 1 + fi + + echo "Mitmproxy is ready" +} + +function main() { + local failed=() + + build_image + create_cluster + install_arc + run_mitmproxy || { + echo "Failed to run mitmproxy" + echo "ARC logs:" + NAMESPACE="${ARC_NAMESPACE}" log_arc + echo "Deleting cluster..." + delete_cluster + exit 1 + } + install_scale_set || { + echo "Failed to run mitmproxy" + echo "ARC logs:" + NAMESPACE="${ARC_NAMESPACE}" log_arc + echo "Deleting cluster..." + delete_cluster + exit 1 + } + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/single-namespace-setup.test.sh b/test/actions.github.com/single-namespace-setup.test.sh new file mode 100755 index 00000000..f6462944 --- /dev/null +++ b/test/actions.github.com/single-namespace-setup.test.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" + +SCALE_SET_NAME="default-$(date +'%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-workflow.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="${SCALE_SET_NAMESPACE}" + +function install_arc() { + echo "Creating namespace ${ARC_NAMESPACE}" + kubectl create namespace "${SCALE_SET_NAMESPACE}" + + echo "Installing ARC" + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + --set flags.watchSingleNamespace="${ARC_NAMESPACE}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --version="${VERSION}" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function main() { + local failed=() + + build_image + create_cluster + + install_arc + install_scale_set + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main diff --git a/test/actions.github.com/update-strategy.test.sh b/test/actions.github.com/update-strategy.test.sh new file mode 100755 index 00000000..f7fce53b --- /dev/null +++ b/test/actions.github.com/update-strategy.test.sh @@ -0,0 +1,146 @@ +#!/bin/bash + +set -euo pipefail + +DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")" + +ROOT_DIR="$(realpath "${DIR}/../..")" + +source "${DIR}/helper.sh" || { + echo "Failed to source helper.sh" + exit 1 +} + +SCALE_SET_NAME="update-strategy-$(date '+%M%S')$(((RANDOM + 100) % 100 + 1))" +SCALE_SET_NAMESPACE="arc-runners" +WORKFLOW_FILE="arc-test-sleepy-matrix.yaml" +ARC_NAME="arc" +ARC_NAMESPACE="arc-systems" + +function install_arc() { + echo "Installing ARC" + + helm install "${ARC_NAME}" \ + --namespace "${ARC_NAMESPACE}" \ + --create-namespace \ + --set image.repository="${IMAGE_NAME}" \ + --set image.tag="${IMAGE_TAG}" \ + --set flags.updateStrategy="eventual" \ + "${ROOT_DIR}/charts/gha-runner-scale-set-controller" \ + --debug + + if ! NAME="${ARC_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_arc; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function install_scale_set() { + echo "Installing scale set ${SCALE_SET_NAME}/${SCALE_SET_NAMESPACE}" + helm install "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --create-namespace \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --debug + + if ! NAME="${SCALE_SET_NAME}" NAMESPACE="${ARC_NAMESPACE}" wait_for_scale_set; then + NAMESPACE="${ARC_NAMESPACE}" log_arc + return 1 + fi +} + +function upgrade_scale_set() { + echo "Upgrading scale set ${SCALE_SET_NAME}/${SCALE_SET_NAMESPACE}" + helm upgrade "${SCALE_SET_NAME}" \ + --namespace "${SCALE_SET_NAMESPACE}" \ + --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ + --set githubConfigSecret.github_token="${GITHUB_TOKEN}" \ + --set template.spec.containers[0].name="runner" \ + --set template.spec.containers[0].image="ghcr.io/actions/actions-runner:latest" \ + --set template.spec.containers[0].command={"/home/runner/run.sh"} \ + --set template.spec.containers[0].env[0].name="TEST" \ + --set template.spec.containers[0].env[0].value="E2E TESTS" \ + "${ROOT_DIR}/charts/gha-runner-scale-set" \ + --version="${VERSION}" \ + --debug + +} + +function assert_listener_deleted() { + local count=0 + while true; do + LISTENER_COUNT="$(kubectl get pods -l actions.github.com/scale-set-name="${SCALE_SET_NAME}" -n "${ARC_NAMESPACE}" --field-selector=status.phase=Running -o=jsonpath='{.items}' | jq 'length')" + RUNNERS_COUNT="$(kubectl get pods -l app.kubernetes.io/component=runner -n "${SCALE_SET_NAMESPACE}" --field-selector=status.phase=Running -o=jsonpath='{.items}' | jq 'length')" + RESOURCES="$(kubectl get pods -A)" + + if [ "${LISTENER_COUNT}" -eq 0 ]; then + echo "Listener has been deleted" + echo "${RESOURCES}" + return 0 + fi + if [ "${count}" -ge 60 ]; then + echo "Timeout waiting for listener to be deleted" + echo "${RESOURCES}" + return 1 + fi + + echo "Waiting for listener to be deleted" + echo "Listener count: ${LISTENER_COUNT} target: 0 | Runners count: ${RUNNERS_COUNT} target: 3" + + sleep 1 + count=$((count + 1)) + done +} + +function assert_listener_recreated() { + count=0 + while true; do + LISTENER_COUNT="$(kubectl get pods -l actions.github.com/scale-set-name="${SCALE_SET_NAME}" -n "${ARC_NAMESPACE}" --field-selector=status.phase=Running -o=jsonpath='{.items}' | jq 'length')" + RUNNERS_COUNT="$(kubectl get pods -l app.kubernetes.io/component=runner -n "${SCALE_SET_NAMESPACE}" --field-selector=status.phase=Running -o=jsonpath='{.items}' | jq 'length')" + RESOURCES="$(kubectl get pods -A)" + + if [ "${LISTENER_COUNT}" -eq 1 ]; then + echo "Listener is up!" + echo "${RESOURCES}" + return 0 + fi + if [ "${count}" -ge 120 ]; then + echo "Timeout waiting for listener to be recreated" + echo "${RESOURCES}" + return 1 + fi + + echo "Waiting for listener to be recreated" + echo "Listener count: ${LISTENER_COUNT} target: 1 | Runners count: ${RUNNERS_COUNT} target: 0" + + sleep 1 + count=$((count + 1)) + done +} + +function main() { + local failed=() + + build_image + create_cluster + install_arc + install_scale_set + + WORKFLOW_FILE="${WORKFLOW_FILE}" SCALE_SET_NAME="${SCALE_SET_NAME}" run_workflow || failed+=("run_workflow") + + upgrade_scale_set || failed+=("upgrade_scale_set") + assert_listener_deleted || failed+=("assert_listener_deleted") + assert_listener_recreated || failed+=("assert_listener_recreated") + + INSTALLATION_NAME="${SCALE_SET_NAME}" NAMESPACE="${SCALE_SET_NAMESPACE}" cleanup_scale_set || failed+=("cleanup_scale_set") + + NAMESPACE="${ARC_NAMESPACE}" log_arc || failed+=("log_arc") + + delete_cluster + + print_results "${failed[@]}" +} + +main From a50d8bfebc3af78c139b405e1940c3d4b87ff202 Mon Sep 17 00:00:00 2001 From: Nikola Jokic Date: Thu, 20 Nov 2025 22:25:52 +0100 Subject: [PATCH 2/8] e2e: move from deprecated openebs charts to new registry (#4321) --- .../auth-proxy-setup.test.sh | 8 +++---- test/actions.github.com/helper.sh | 23 +++++++++++-------- .../kubernetes-mode-setup.test.sh | 8 +++---- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/test/actions.github.com/auth-proxy-setup.test.sh b/test/actions.github.com/auth-proxy-setup.test.sh index d13054fd..e22e02b5 100755 --- a/test/actions.github.com/auth-proxy-setup.test.sh +++ b/test/actions.github.com/auth-proxy-setup.test.sh @@ -15,10 +15,10 @@ ARC_NAME="arc" ARC_NAMESPACE="arc-systems" function install_arc() { - echo "Install openebs/dynamic-localpv-provisioner" - helm repo add openebs https://openebs.github.io/charts - helm repo update - helm install openebs openebs/openebs -n openebs --create-namespace + install_openebs || { + echo "OpenEBS installation failed" + return 1 + } echo "Creating namespace ${ARC_NAMESPACE}" kubectl create namespace "${SCALE_SET_NAMESPACE}" diff --git a/test/actions.github.com/helper.sh b/test/actions.github.com/helper.sh index 32718035..c6405af8 100644 --- a/test/actions.github.com/helper.sh +++ b/test/actions.github.com/helper.sh @@ -14,7 +14,8 @@ export IMAGE_TAG="${VERSION}" export IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" export PLATFORMS="linux/amd64" -export COMMIT_SHA="$(git rev-parse HEAD)" +COMMIT_SHA="$(git rev-parse HEAD)" +export COMMIT_SHA function build_image() { echo "Building ARC image ${IMAGE}" @@ -111,13 +112,6 @@ function cleanup_scale_set() { kubectl wait --timeout=40s --for=delete autoscalingrunnersets -n "${NAMESPACE}" -l app.kubernetes.io/instance="${INSTALLATION_NAME}" } -function install_openebs() { - echo "Install openebs/dynamic-localpv-provisioner" - helm repo add openebs https://openebs.github.io/charts - helm repo update - helm install openebs openebs/openebs --namespace openebs --create-namespace -} - function print_results() { local failed=("$@") @@ -138,7 +132,8 @@ function run_workflow() { echo "Checking if the workflow file exists" gh workflow view -R "${TARGET_ORG}/${TARGET_REPO}" "${WORKFLOW_FILE}" || return 1 - local queue_time="$(date -u +%FT%TZ)" + local queue_time + queue_time="$(date -u +%FT%TZ)" echo "Running workflow ${WORKFLOW_FILE}" gh workflow run -R "${TARGET_ORG}/${TARGET_REPO}" "${WORKFLOW_FILE}" --ref main -f arc_name="${SCALE_SET_NAME}" || return 1 @@ -164,7 +159,8 @@ function run_workflow() { done echo "Waiting for run to complete" - local code=$(gh run watch "${run_id}" -R "${TARGET_ORG}/${TARGET_REPO}" --exit-status &>/dev/null) + local code + code=$(gh run watch "${run_id}" -R "${TARGET_ORG}/${TARGET_REPO}" --exit-status &>/dev/null) if [[ "${code}" -ne 0 ]]; then echo "Run failed with exit code ${code}" return 1 @@ -191,3 +187,10 @@ function retry() { fi done } + +function install_openebs() { + echo "Install openebs/dynamic-localpv-provisioner" + helm repo add openebs https://openebs.github.io/openebs + helm repo update + helm install openebs openebs/openebs -n openebs --create-namespace +} diff --git a/test/actions.github.com/kubernetes-mode-setup.test.sh b/test/actions.github.com/kubernetes-mode-setup.test.sh index 8a2dd1fe..7ac583b9 100755 --- a/test/actions.github.com/kubernetes-mode-setup.test.sh +++ b/test/actions.github.com/kubernetes-mode-setup.test.sh @@ -15,10 +15,10 @@ ARC_NAME="arc" ARC_NAMESPACE="arc-systems" function install_arc() { - echo "Install openebs/dynamic-localpv-provisioner" - helm repo add openebs https://openebs.github.io/charts - helm repo update - helm install openebs openebs/openebs -n openebs --create-namespace + install_openebs || { + echo "OpenEBS installation failed" + return 1 + } echo "Creating namespace ${ARC_NAMESPACE}" kubectl create namespace "${SCALE_SET_NAMESPACE}" From 6d07b8d853378575f70c8f4fe6a5fbb21974c93f Mon Sep 17 00:00:00 2001 From: Nikola Jokic Date: Thu, 20 Nov 2025 23:06:27 +0100 Subject: [PATCH 3/8] Add ephemeral runner finalizer during creation and check finalizer without requeue (#4320) --- .github/workflows/gha-e2e-tests.yaml | 53 +++----- .../ephemeralrunner_controller.go | 24 +--- .../ephemeralrunnerset_controller_test.go | 118 +++++++++++------- .../actions.github.com/resourcebuilder.go | 5 +- hack/e2e-test.sh | 7 +- .../anonymous-proxy-setup.test.sh | 2 +- 6 files changed, 104 insertions(+), 105 deletions(-) diff --git a/.github/workflows/gha-e2e-tests.yaml b/.github/workflows/gha-e2e-tests.yaml index f35c7a2e..5fd3af44 100644 --- a/.github/workflows/gha-e2e-tests.yaml +++ b/.github/workflows/gha-e2e-tests.yaml @@ -30,9 +30,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} steps: - uses: actions/checkout@v5 with: @@ -48,6 +45,8 @@ jobs: - name: Run default setup test run: hack/e2e-test.sh default-setup + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash default-setup: @@ -145,10 +144,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -164,6 +159,8 @@ jobs: - name: Run single namespace setup test run: hack/e2e-test.sh single-namespace-setup + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash single-namespace-setup: @@ -263,10 +260,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -282,6 +275,8 @@ jobs: - name: Run dind mode setup test run: hack/e2e-test.sh dind-mode-setup + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash dind-mode-setup: @@ -380,10 +375,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -399,6 +390,8 @@ jobs: - name: Run kubernetes mode setup test run: hack/e2e-test.sh kubernetes-mode-setup + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash kubernetes-mode-setup: @@ -506,10 +499,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -525,6 +514,8 @@ jobs: - name: Run single namespace setup test run: hack/e2e-test.sh single-namespace-setup + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash auth-proxy-setup: @@ -634,10 +625,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -653,6 +640,8 @@ jobs: - name: Run anonymous proxy setup test run: hack/e2e-test.sh anonymous-proxy-setup + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash anonymous-proxy-setup: @@ -756,10 +745,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -775,6 +760,8 @@ jobs: - name: Run self signed CA setup test run: hack/e2e-test.sh self-signed-ca-setup + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash self-signed-ca-setup: @@ -903,10 +890,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -922,6 +905,8 @@ jobs: - name: Run update strategy test run: hack/e2e-test.sh update-strategy + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash update-strategy-tests: @@ -1100,10 +1085,6 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - TARGET_ORG: ${{ env.TARGET_ORG }} - TARGET_REPO: ${{ env.TARGET_REPO }} - steps: - uses: actions/checkout@v5 with: @@ -1119,6 +1100,8 @@ jobs: - name: Run init with min runners test run: hack/e2e-test.sh init-with-min-runners + env: + GITHUB_TOKEN: "${{steps.config-token.outputs.token}}" shell: bash init-with-min-runners: diff --git a/controllers/actions.github.com/ephemeralrunner_controller.go b/controllers/actions.github.com/ephemeralrunner_controller.go index 48185320..ec67b833 100644 --- a/controllers/actions.github.com/ephemeralrunner_controller.go +++ b/controllers/actions.github.com/ephemeralrunner_controller.go @@ -154,31 +154,17 @@ func (r *EphemeralRunnerReconciler) Reconcile(ctx context.Context, req ctrl.Requ return ctrl.Result{}, nil } - if !controllerutil.ContainsFinalizer(ephemeralRunner, ephemeralRunnerFinalizerName) { - log.Info("Adding finalizer") + addFinalizers := !controllerutil.ContainsFinalizer(ephemeralRunner, ephemeralRunnerFinalizerName) || !controllerutil.ContainsFinalizer(ephemeralRunner, ephemeralRunnerActionsFinalizerName) + if addFinalizers { + log.Info("Adding finalizers") if err := patch(ctx, r.Client, ephemeralRunner, func(obj *v1alpha1.EphemeralRunner) { controllerutil.AddFinalizer(obj, ephemeralRunnerFinalizerName) + controllerutil.AddFinalizer(obj, ephemeralRunnerActionsFinalizerName) }); err != nil { log.Error(err, "Failed to update with finalizer set") return ctrl.Result{}, err } - - log.Info("Successfully added finalizer") - return ctrl.Result{}, nil - } - - if !controllerutil.ContainsFinalizer(ephemeralRunner, ephemeralRunnerActionsFinalizerName) { - log.Info("Adding runner registration finalizer") - err := patch(ctx, r.Client, ephemeralRunner, func(obj *v1alpha1.EphemeralRunner) { - controllerutil.AddFinalizer(obj, ephemeralRunnerActionsFinalizerName) - }) - if err != nil { - log.Error(err, "Failed to update with runner registration finalizer set") - return ctrl.Result{}, err - } - - log.Info("Successfully added runner registration finalizer") - return ctrl.Result{}, nil + log.Info("Successfully added finalizers") } secret := new(corev1.Secret) diff --git a/controllers/actions.github.com/ephemeralrunnerset_controller_test.go b/controllers/actions.github.com/ephemeralrunnerset_controller_test.go index a23d537a..443863eb 100644 --- a/controllers/actions.github.com/ephemeralrunnerset_controller_test.go +++ b/controllers/actions.github.com/ephemeralrunnerset_controller_test.go @@ -32,9 +32,8 @@ import ( ) const ( - ephemeralRunnerSetTestTimeout = time.Second * 20 - ephemeralRunnerSetTestInterval = time.Millisecond * 250 - ephemeralRunnerSetTestGitHubToken = "gh_token" + ephemeralRunnerSetTestTimeout = time.Second * 20 + ephemeralRunnerSetTestInterval = time.Millisecond * 250 ) func TestPrecomputedConstants(t *testing.T) { @@ -119,8 +118,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { Consistently( func() (int, error) { runnerList := new(v1alpha1.EphemeralRunnerList) - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } @@ -153,8 +151,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { Eventually( func() (int, error) { runnerList := new(v1alpha1.EphemeralRunnerList) - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } @@ -172,8 +169,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { } if refetch { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } } @@ -215,8 +211,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { Eventually( func() (int, error) { runnerList := new(v1alpha1.EphemeralRunnerList) - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } @@ -234,8 +229,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { } if refetch { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } } @@ -253,8 +247,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { Eventually( func() (int, error) { runnerList := new(v1alpha1.EphemeralRunnerList) - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } @@ -299,8 +292,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } @@ -326,8 +318,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } @@ -351,7 +342,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -378,7 +369,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -403,7 +394,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -429,7 +420,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -456,7 +447,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -481,7 +472,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Consistently( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -508,7 +499,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -545,7 +536,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { // We should have 3 runners, and have no Succeeded ones Eventually( func() error { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return err } @@ -582,7 +573,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -607,7 +598,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() error { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return err } @@ -648,7 +639,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { // We should have 1 runner up and pending Eventually( func() error { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return err } @@ -675,7 +666,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -702,7 +693,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -728,7 +719,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() error { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return err } @@ -772,8 +763,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Consistently( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) - if err != nil { + if err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace); err != nil { return -1, err } @@ -799,7 +789,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -826,7 +816,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -853,7 +843,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() error { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return err } @@ -897,7 +887,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList = new(v1alpha1.EphemeralRunnerList) Eventually( func() error { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return err } @@ -938,7 +928,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { runnerList := new(v1alpha1.EphemeralRunnerList) Eventually( func() (bool, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return false, err } @@ -1046,7 +1036,7 @@ var _ = Describe("Test EphemeralRunnerSet controller", func() { Eventually( func() (int, error) { runnerList = new(v1alpha1.EphemeralRunnerList) - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -1208,7 +1198,7 @@ var _ = Describe("Test EphemeralRunnerSet controller with proxy settings", func( Eventually(func(g Gomega) { runnerList := new(v1alpha1.EphemeralRunnerList) - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) g.Expect(err).NotTo(HaveOccurred(), "failed to list EphemeralRunners") for _, runner := range runnerList.Items { @@ -1226,7 +1216,7 @@ var _ = Describe("Test EphemeralRunnerSet controller with proxy settings", func( Eventually( func(g Gomega) (int, error) { runnerList := new(v1alpha1.EphemeralRunnerList) - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -1245,7 +1235,7 @@ var _ = Describe("Test EphemeralRunnerSet controller with proxy settings", func( } if refetch { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -1260,6 +1250,18 @@ var _ = Describe("Test EphemeralRunnerSet controller with proxy settings", func( err = k8sClient.Delete(ctx, ephemeralRunnerSet) Expect(err).NotTo(HaveOccurred(), "failed to delete EphemeralRunnerSet") + Eventually(func(g Gomega) (int, error) { + runnerList := new(v1alpha1.EphemeralRunnerList) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) + if err != nil { + return -1, err + } + return len(runnerList.Items), nil + }, + ephemeralRunnerSetTestTimeout, + ephemeralRunnerSetTestInterval, + ).Should(BeEquivalentTo(0), "EphemeralRunners should be deleted") + // Assert that the proxy secret is deleted Eventually(func(g Gomega) { proxySecret := &corev1.Secret{} @@ -1343,7 +1345,7 @@ var _ = Describe("Test EphemeralRunnerSet controller with proxy settings", func( runnerList := new(v1alpha1.EphemeralRunnerList) Eventually(func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -1490,7 +1492,7 @@ var _ = Describe("Test EphemeralRunnerSet controller with custom root CA", func( runnerList := new(v1alpha1.EphemeralRunnerList) Eventually(func() (int, error) { - err := k8sClient.List(ctx, runnerList, client.InNamespace(ephemeralRunnerSet.Namespace)) + err := listEphemeralRunnersAndRemoveFinalizers(ctx, k8sClient, runnerList, ephemeralRunnerSet.Namespace) if err != nil { return -1, err } @@ -1529,3 +1531,27 @@ var _ = Describe("Test EphemeralRunnerSet controller with custom root CA", func( ).Should(BeTrue(), "server was not called") }) }) + +// helper function to remove ephemeral runners since in the test, ephemeral runner reconciler is not started +func listEphemeralRunnersAndRemoveFinalizers(ctx context.Context, k8sClient client.Client, list *v1alpha1.EphemeralRunnerList, namespace string) error { + err := k8sClient.List(ctx, list, client.InNamespace(namespace)) + if err != nil { + return err + } + + // Since we are not starting ephemeral runner reconciler, ignore + liveItems := make([]v1alpha1.EphemeralRunner, 0) + for _, item := range list.Items { + if !item.DeletionTimestamp.IsZero() { + if err := patch(ctx, k8sClient, &item, func(runner *v1alpha1.EphemeralRunner) { + runner.Finalizers = []string{} + }); err != nil { + return err + } + continue + } + liveItems = append(liveItems, item) + } + list.Items = liveItems + return nil +} diff --git a/controllers/actions.github.com/resourcebuilder.go b/controllers/actions.github.com/resourcebuilder.go index 6b9ef880..bf188d6d 100644 --- a/controllers/actions.github.com/resourcebuilder.go +++ b/controllers/actions.github.com/resourcebuilder.go @@ -572,12 +572,15 @@ func (b *ResourceBuilder) newEphemeralRunner(ephemeralRunnerSet *v1alpha1.Epheme annotations[AnnotationKeyPatchID] = strconv.Itoa(ephemeralRunnerSet.Spec.PatchID) return &v1alpha1.EphemeralRunner{ - TypeMeta: metav1.TypeMeta{}, ObjectMeta: metav1.ObjectMeta{ GenerateName: ephemeralRunnerSet.Name + "-runner-", Namespace: ephemeralRunnerSet.Namespace, Labels: labels, Annotations: annotations, + Finalizers: []string{ + ephemeralRunnerFinalizerName, + ephemeralRunnerActionsFinalizerName, + }, OwnerReferences: []metav1.OwnerReference{ { APIVersion: ephemeralRunnerSet.GetObjectKind().GroupVersionKind().GroupVersion().String(), diff --git a/hack/e2e-test.sh b/hack/e2e-test.sh index d532662e..fa0b000c 100755 --- a/hack/e2e-test.sh +++ b/hack/e2e-test.sh @@ -11,11 +11,12 @@ export PLATFORMS="linux/amd64" TARGETS=() function set_targets() { - local cases="$(find "${TEST_DIR}" -name '*.test.sh' | sed "s#^${TEST_DIR}/##g" )" + local cases + cases="$(find "${TEST_DIR}" -name '*.test.sh' | sed "s#^${TEST_DIR}/##g")" mapfile -t TARGETS < <(echo "${cases}") - echo $TARGETS + echo "${TARGETS[@]}" } function env_test() { @@ -89,4 +90,4 @@ function main() { fi } -main $@ +main "$@" diff --git a/test/actions.github.com/anonymous-proxy-setup.test.sh b/test/actions.github.com/anonymous-proxy-setup.test.sh index fb79fb10..a60e51c6 100755 --- a/test/actions.github.com/anonymous-proxy-setup.test.sh +++ b/test/actions.github.com/anonymous-proxy-setup.test.sh @@ -41,7 +41,7 @@ function install_squid() { function install_scale_set() { echo "Installing scale set ${SCALE_SET_NAMESPACE}/${SCALE_SET_NAME}" - echo helm install "${SCALE_SET_NAME}" \ + helm install "${SCALE_SET_NAME}" \ --namespace "${SCALE_SET_NAMESPACE}" \ --create-namespace \ --set githubConfigUrl="https://github.com/${TARGET_ORG}/${TARGET_REPO}" \ From 5a6bfc937afd8c68102ab91407e2eebd23c60dd2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 10:10:16 +0100 Subject: [PATCH 4/8] Updates: runner to v2.330.0 (#4319) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- Makefile | 2 +- runner/Makefile | 2 +- runner/VERSION | 2 +- test/e2e/e2e_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c7ecf843..6df0a7fd 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ endif DOCKER_USER ?= $(shell echo ${DOCKER_IMAGE_NAME} | cut -d / -f1) VERSION ?= dev COMMIT_SHA = $(shell git rev-parse HEAD) -RUNNER_VERSION ?= 2.329.0 +RUNNER_VERSION ?= 2.330.0 TARGETPLATFORM ?= $(shell arch) RUNNER_NAME ?= ${DOCKER_USER}/actions-runner RUNNER_TAG ?= ${VERSION} diff --git a/runner/Makefile b/runner/Makefile index 78151267..b19ecb1d 100644 --- a/runner/Makefile +++ b/runner/Makefile @@ -6,7 +6,7 @@ DIND_ROOTLESS_RUNNER_NAME ?= ${DOCKER_USER}/actions-runner-dind-rootless OS_IMAGE ?= ubuntu-22.04 TARGETPLATFORM ?= $(shell arch) -RUNNER_VERSION ?= 2.329.0 +RUNNER_VERSION ?= 2.330.0 RUNNER_CONTAINER_HOOKS_VERSION ?= 0.8.0 DOCKER_VERSION ?= 28.0.4 diff --git a/runner/VERSION b/runner/VERSION index b10009d8..b3fac19e 100644 --- a/runner/VERSION +++ b/runner/VERSION @@ -1,2 +1,2 @@ -RUNNER_VERSION=2.329.0 +RUNNER_VERSION=2.330.0 RUNNER_CONTAINER_HOOKS_VERSION=0.8.0 \ No newline at end of file diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 68f4a284..a02b9cf1 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -36,7 +36,7 @@ var ( testResultCMNamePrefix = "test-result-" - RunnerVersion = "2.329.0" + RunnerVersion = "2.330.0" RunnerContainerHooksVersion = "0.8.0" ) From 95d2107a6ad8a0c50ae9d11a50b214e4f4e6266d Mon Sep 17 00:00:00 2001 From: Nikola Jokic Date: Fri, 21 Nov 2025 14:20:44 +0100 Subject: [PATCH 5/8] Code style changes on the controller (#4324) --- .../autoscalinglistener_controller_test.go | 5 +- .../autoscalingrunnerset_controller.go | 47 ++++++++--------- .../autoscalingrunnerset_controller_test.go | 9 ++-- controllers/actions.github.com/constants.go | 3 +- .../ephemeralrunner_controller.go | 2 +- .../actions.github.com/helpers_test.go | 4 +- .../actions.github.com/resourcebuilder.go | 51 ++++++------------- .../resourcebuilder_test.go | 11 ++-- 8 files changed, 56 insertions(+), 76 deletions(-) diff --git a/controllers/actions.github.com/autoscalinglistener_controller_test.go b/controllers/actions.github.com/autoscalinglistener_controller_test.go index 407dd12a..36150eb9 100644 --- a/controllers/actions.github.com/autoscalinglistener_controller_test.go +++ b/controllers/actions.github.com/autoscalinglistener_controller_test.go @@ -26,9 +26,8 @@ import ( ) const ( - autoscalingListenerTestTimeout = time.Second * 20 - autoscalingListenerTestInterval = time.Millisecond * 250 - autoscalingListenerTestGitHubToken = "gh_token" + autoscalingListenerTestTimeout = time.Second * 20 + autoscalingListenerTestInterval = time.Millisecond * 250 ) var _ = Describe("Test AutoScalingListener controller", func() { diff --git a/controllers/actions.github.com/autoscalingrunnerset_controller.go b/controllers/actions.github.com/autoscalingrunnerset_controller.go index 1a7a83b9..bcab0c01 100644 --- a/controllers/actions.github.com/autoscalingrunnerset_controller.go +++ b/controllers/actions.github.com/autoscalingrunnerset_controller.go @@ -48,7 +48,7 @@ const ( annotationKeyValuesHash = "actions.github.com/values-hash" autoscalingRunnerSetFinalizerName = "autoscalingrunnerset.actions.github.com/finalizer" - runnerScaleSetIdAnnotationKey = "runner-scale-set-id" + runnerScaleSetIDAnnotationKey = "runner-scale-set-id" ) type UpdateStrategy string @@ -180,14 +180,14 @@ func (r *AutoscalingRunnerSetReconciler) Reconcile(ctx context.Context, req ctrl return ctrl.Result{}, nil } - scaleSetIdRaw, ok := autoscalingRunnerSet.Annotations[runnerScaleSetIdAnnotationKey] + scaleSetIDRaw, ok := autoscalingRunnerSet.Annotations[runnerScaleSetIDAnnotationKey] if !ok { // Need to create a new runner scale set on Actions service log.Info("Runner scale set id annotation does not exist. Creating a new runner scale set.") return r.createRunnerScaleSet(ctx, autoscalingRunnerSet, log) } - if id, err := strconv.Atoi(scaleSetIdRaw); err != nil || id <= 0 { + if id, err := strconv.Atoi(scaleSetIDRaw); err != nil || id <= 0 { log.Info("Runner scale set id annotation is not an id, or is <= 0. Creating a new runner scale set.") // something modified the scaleSetId. Try to create one return r.createRunnerScaleSet(ctx, autoscalingRunnerSet, log) @@ -403,7 +403,7 @@ func (r *AutoscalingRunnerSetReconciler) createRunnerScaleSet(ctx context.Contex return ctrl.Result{}, err } - runnerGroupId := 1 + runnerGroupID := 1 if len(autoscalingRunnerSet.Spec.RunnerGroup) > 0 { runnerGroup, err := actionsClient.GetRunnerGroupByName(ctx, autoscalingRunnerSet.Spec.RunnerGroup) if err != nil { @@ -411,14 +411,14 @@ func (r *AutoscalingRunnerSetReconciler) createRunnerScaleSet(ctx context.Contex return ctrl.Result{}, err } - runnerGroupId = int(runnerGroup.ID) + runnerGroupID = int(runnerGroup.ID) } - runnerScaleSet, err := actionsClient.GetRunnerScaleSet(ctx, runnerGroupId, autoscalingRunnerSet.Spec.RunnerScaleSetName) + runnerScaleSet, err := actionsClient.GetRunnerScaleSet(ctx, runnerGroupID, autoscalingRunnerSet.Spec.RunnerScaleSetName) if err != nil { logger.Error(err, "Failed to get runner scale set from Actions service", "runnerGroupId", - strconv.Itoa(runnerGroupId), + strconv.Itoa(runnerGroupID), "runnerScaleSetName", autoscalingRunnerSet.Spec.RunnerScaleSetName) return ctrl.Result{}, err @@ -429,7 +429,7 @@ func (r *AutoscalingRunnerSetReconciler) createRunnerScaleSet(ctx context.Contex ctx, &actions.RunnerScaleSet{ Name: autoscalingRunnerSet.Spec.RunnerScaleSetName, - RunnerGroupId: runnerGroupId, + RunnerGroupId: runnerGroupID, Labels: []actions.Label{ { Name: autoscalingRunnerSet.Spec.RunnerScaleSetName, @@ -466,7 +466,7 @@ func (r *AutoscalingRunnerSetReconciler) createRunnerScaleSet(ctx context.Contex logger.Info("Adding runner scale set ID, name and runner group name as an annotation and url labels") if err = patch(ctx, r.Client, autoscalingRunnerSet, func(obj *v1alpha1.AutoscalingRunnerSet) { obj.Annotations[AnnotationKeyGitHubRunnerScaleSetName] = runnerScaleSet.Name - obj.Annotations[runnerScaleSetIdAnnotationKey] = strconv.Itoa(runnerScaleSet.Id) + obj.Annotations[runnerScaleSetIDAnnotationKey] = strconv.Itoa(runnerScaleSet.Id) obj.Annotations[AnnotationKeyGitHubRunnerGroupName] = runnerScaleSet.RunnerGroupName if err := applyGitHubURLLabels(obj.Spec.GitHubConfigUrl, obj.Labels); err != nil { // should never happen logger.Error(err, "Failed to apply GitHub URL labels") @@ -484,7 +484,7 @@ func (r *AutoscalingRunnerSetReconciler) createRunnerScaleSet(ctx context.Contex } func (r *AutoscalingRunnerSetReconciler) updateRunnerScaleSetRunnerGroup(ctx context.Context, autoscalingRunnerSet *v1alpha1.AutoscalingRunnerSet, logger logr.Logger) (ctrl.Result, error) { - runnerScaleSetId, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIdAnnotationKey]) + runnerScaleSetID, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIDAnnotationKey]) if err != nil { logger.Error(err, "Failed to parse runner scale set ID") return ctrl.Result{}, err @@ -496,7 +496,7 @@ func (r *AutoscalingRunnerSetReconciler) updateRunnerScaleSetRunnerGroup(ctx con return ctrl.Result{}, err } - runnerGroupId := 1 + runnerGroupID := 1 if len(autoscalingRunnerSet.Spec.RunnerGroup) > 0 { runnerGroup, err := actionsClient.GetRunnerGroupByName(ctx, autoscalingRunnerSet.Spec.RunnerGroup) if err != nil { @@ -504,12 +504,12 @@ func (r *AutoscalingRunnerSetReconciler) updateRunnerScaleSetRunnerGroup(ctx con return ctrl.Result{}, err } - runnerGroupId = int(runnerGroup.ID) + runnerGroupID = int(runnerGroup.ID) } - updatedRunnerScaleSet, err := actionsClient.UpdateRunnerScaleSet(ctx, runnerScaleSetId, &actions.RunnerScaleSet{RunnerGroupId: runnerGroupId}) + updatedRunnerScaleSet, err := actionsClient.UpdateRunnerScaleSet(ctx, runnerScaleSetID, &actions.RunnerScaleSet{RunnerGroupId: runnerGroupID}) if err != nil { - logger.Error(err, "Failed to update runner scale set", "runnerScaleSetId", runnerScaleSetId) + logger.Error(err, "Failed to update runner scale set", "runnerScaleSetId", runnerScaleSetID) return ctrl.Result{}, err } @@ -527,7 +527,7 @@ func (r *AutoscalingRunnerSetReconciler) updateRunnerScaleSetRunnerGroup(ctx con } func (r *AutoscalingRunnerSetReconciler) updateRunnerScaleSetName(ctx context.Context, autoscalingRunnerSet *v1alpha1.AutoscalingRunnerSet, logger logr.Logger) (ctrl.Result, error) { - runnerScaleSetId, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIdAnnotationKey]) + runnerScaleSetID, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIDAnnotationKey]) if err != nil { logger.Error(err, "Failed to parse runner scale set ID") return ctrl.Result{}, err @@ -544,9 +544,9 @@ func (r *AutoscalingRunnerSetReconciler) updateRunnerScaleSetName(ctx context.Co return ctrl.Result{}, err } - updatedRunnerScaleSet, err := actionsClient.UpdateRunnerScaleSet(ctx, runnerScaleSetId, &actions.RunnerScaleSet{Name: autoscalingRunnerSet.Spec.RunnerScaleSetName}) + updatedRunnerScaleSet, err := actionsClient.UpdateRunnerScaleSet(ctx, runnerScaleSetID, &actions.RunnerScaleSet{Name: autoscalingRunnerSet.Spec.RunnerScaleSetName}) if err != nil { - logger.Error(err, "Failed to update runner scale set", "runnerScaleSetId", runnerScaleSetId) + logger.Error(err, "Failed to update runner scale set", "runnerScaleSetId", runnerScaleSetID) return ctrl.Result{}, err } @@ -563,7 +563,7 @@ func (r *AutoscalingRunnerSetReconciler) updateRunnerScaleSetName(ctx context.Co } func (r *AutoscalingRunnerSetReconciler) deleteRunnerScaleSet(ctx context.Context, autoscalingRunnerSet *v1alpha1.AutoscalingRunnerSet, logger logr.Logger) error { - scaleSetId, ok := autoscalingRunnerSet.Annotations[runnerScaleSetIdAnnotationKey] + scaleSetID, ok := autoscalingRunnerSet.Annotations[runnerScaleSetIDAnnotationKey] if !ok { // Annotation not being present can occur in 3 scenarios // 1. Scale set is never created. @@ -580,7 +580,7 @@ func (r *AutoscalingRunnerSetReconciler) deleteRunnerScaleSet(ctx context.Contex return nil } logger.Info("Deleting the runner scale set from Actions service") - runnerScaleSetId, err := strconv.Atoi(scaleSetId) + runnerScaleSetID, err := strconv.Atoi(scaleSetID) if err != nil { // If the annotation is not set correctly, we are going to get stuck in a loop trying to parse the scale set id. // If the configuration is invalid (secret does not exist for example), we never got to the point to create runner set. @@ -595,17 +595,17 @@ func (r *AutoscalingRunnerSetReconciler) deleteRunnerScaleSet(ctx context.Contex return err } - err = actionsClient.DeleteRunnerScaleSet(ctx, runnerScaleSetId) + err = actionsClient.DeleteRunnerScaleSet(ctx, runnerScaleSetID) if err != nil { - logger.Error(err, "Failed to delete runner scale set", "runnerScaleSetId", runnerScaleSetId) + logger.Error(err, "Failed to delete runner scale set", "runnerScaleSetId", runnerScaleSetID) return err } err = patch(ctx, r.Client, autoscalingRunnerSet, func(obj *v1alpha1.AutoscalingRunnerSet) { - delete(obj.Annotations, runnerScaleSetIdAnnotationKey) + delete(obj.Annotations, runnerScaleSetIDAnnotationKey) }) if err != nil { - logger.Error(err, "Failed to patch autoscaling runner set with annotation removed", "annotation", runnerScaleSetIdAnnotationKey) + logger.Error(err, "Failed to patch autoscaling runner set with annotation removed", "annotation", runnerScaleSetIDAnnotationKey) return err } @@ -1006,6 +1006,7 @@ func (c *autoscalingRunnerSetFinalizerDependencyCleaner) removeManagerRoleFinali // NOTE: if this is logic should be used for other resources, // consider using generics + type EphemeralRunnerSets struct { list *v1alpha1.EphemeralRunnerSetList sorted bool diff --git a/controllers/actions.github.com/autoscalingrunnerset_controller_test.go b/controllers/actions.github.com/autoscalingrunnerset_controller_test.go index 7411b6b9..620f3ab5 100644 --- a/controllers/actions.github.com/autoscalingrunnerset_controller_test.go +++ b/controllers/actions.github.com/autoscalingrunnerset_controller_test.go @@ -34,9 +34,8 @@ import ( ) const ( - autoscalingRunnerSetTestTimeout = time.Second * 20 - autoscalingRunnerSetTestInterval = time.Millisecond * 250 - autoscalingRunnerSetTestGitHubToken = "gh_token" + autoscalingRunnerSetTestTimeout = time.Second * 20 + autoscalingRunnerSetTestInterval = time.Millisecond * 250 ) var _ = Describe("Test AutoScalingRunnerSet controller", Ordered, func() { @@ -141,7 +140,7 @@ var _ = Describe("Test AutoScalingRunnerSet controller", Ordered, func() { return "", err } - if _, ok := created.Annotations[runnerScaleSetIdAnnotationKey]; !ok { + if _, ok := created.Annotations[runnerScaleSetIDAnnotationKey]; !ok { return "", nil } @@ -149,7 +148,7 @@ var _ = Describe("Test AutoScalingRunnerSet controller", Ordered, func() { return "", nil } - return fmt.Sprintf("%s_%s", created.Annotations[runnerScaleSetIdAnnotationKey], created.Annotations[AnnotationKeyGitHubRunnerGroupName]), nil + return fmt.Sprintf("%s_%s", created.Annotations[runnerScaleSetIDAnnotationKey], created.Annotations[AnnotationKeyGitHubRunnerGroupName]), nil }, autoscalingRunnerSetTestTimeout, autoscalingRunnerSetTestInterval).Should(BeEquivalentTo("1_testgroup"), "RunnerScaleSet should be created/fetched and update the AutoScalingRunnerSet's annotation") diff --git a/controllers/actions.github.com/constants.go b/controllers/actions.github.com/constants.go index cbf3309c..6619a504 100644 --- a/controllers/actions.github.com/constants.go +++ b/controllers/actions.github.com/constants.go @@ -36,7 +36,8 @@ const ( LabelKeyGitHubRepository = "actions.github.com/repository" ) -// Finalizer used to protect resources from deletion while AutoscalingRunnerSet is running +// AutoscalingRunnerSetCleanupFinalizerName is a finalizer used to protect resources +// from deletion while AutoscalingRunnerSet is running const AutoscalingRunnerSetCleanupFinalizerName = "actions.github.com/cleanup-protection" const ( diff --git a/controllers/actions.github.com/ephemeralrunner_controller.go b/controllers/actions.github.com/ephemeralrunner_controller.go index ec67b833..80a012be 100644 --- a/controllers/actions.github.com/ephemeralrunner_controller.go +++ b/controllers/actions.github.com/ephemeralrunner_controller.go @@ -689,7 +689,7 @@ func (r *EphemeralRunnerReconciler) createPod(ctx context.Context, runner *v1alp } log.Info("Creating new pod for ephemeral runner") - newPod := r.newEphemeralRunnerPod(ctx, runner, secret, envs...) + newPod := r.newEphemeralRunnerPod(runner, secret, envs...) if err := ctrl.SetControllerReference(runner, newPod, r.Scheme); err != nil { log.Error(err, "Failed to set controller reference to a new pod") diff --git a/controllers/actions.github.com/helpers_test.go b/controllers/actions.github.com/helpers_test.go index c3c0ef6b..f8f9e810 100644 --- a/controllers/actions.github.com/helpers_test.go +++ b/controllers/actions.github.com/helpers_test.go @@ -42,11 +42,11 @@ func createNamespace(t ginkgo.GinkgoTInterface, client client.Client) (*corev1.N ObjectMeta: metav1.ObjectMeta{Name: "testns-autoscaling" + RandStringRunes(5)}, } - err := k8sClient.Create(context.Background(), ns) + err := client.Create(context.Background(), ns) require.NoError(t, err) t.Cleanup(func() { - err := k8sClient.Delete(context.Background(), ns) + err := client.Delete(context.Background(), ns) require.NoError(t, err) }) diff --git a/controllers/actions.github.com/resourcebuilder.go b/controllers/actions.github.com/resourcebuilder.go index bf188d6d..98b894a6 100644 --- a/controllers/actions.github.com/resourcebuilder.go +++ b/controllers/actions.github.com/resourcebuilder.go @@ -2,7 +2,6 @@ package actionsgithubcom import ( "bytes" - "context" "encoding/json" "fmt" "maps" @@ -83,7 +82,7 @@ func boolPtr(v bool) *bool { } func (b *ResourceBuilder) newAutoScalingListener(autoscalingRunnerSet *v1alpha1.AutoscalingRunnerSet, ephemeralRunnerSet *v1alpha1.EphemeralRunnerSet, namespace, image string, imagePullSecrets []corev1.LocalObjectReference) (*v1alpha1.AutoscalingListener, error) { - runnerScaleSetId, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIdAnnotationKey]) + runnerScaleSetID, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIDAnnotationKey]) if err != nil { return nil, err } @@ -125,7 +124,7 @@ func (b *ResourceBuilder) newAutoScalingListener(autoscalingRunnerSet *v1alpha1. GitHubConfigUrl: autoscalingRunnerSet.Spec.GitHubConfigUrl, GitHubConfigSecret: autoscalingRunnerSet.Spec.GitHubConfigSecret, VaultConfig: autoscalingRunnerSet.VaultConfig(), - RunnerScaleSetId: runnerScaleSetId, + RunnerScaleSetId: runnerScaleSetID, AutoscalingRunnerSetNamespace: autoscalingRunnerSet.Namespace, AutoscalingRunnerSetName: autoscalingRunnerSet.Name, EphemeralRunnerSetName: ephemeralRunnerSet.Name, @@ -496,7 +495,7 @@ func (b *ResourceBuilder) newScaleSetListenerRoleBinding(autoscalingListener *v1 } func (b *ResourceBuilder) newEphemeralRunnerSet(autoscalingRunnerSet *v1alpha1.AutoscalingRunnerSet) (*v1alpha1.EphemeralRunnerSet, error) { - runnerScaleSetId, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIdAnnotationKey]) + runnerScaleSetID, err := strconv.Atoi(autoscalingRunnerSet.Annotations[runnerScaleSetIDAnnotationKey]) if err != nil { return nil, err } @@ -541,7 +540,7 @@ func (b *ResourceBuilder) newEphemeralRunnerSet(autoscalingRunnerSet *v1alpha1.A Spec: v1alpha1.EphemeralRunnerSetSpec{ Replicas: 0, EphemeralRunnerSpec: v1alpha1.EphemeralRunnerSpec{ - RunnerScaleSetId: runnerScaleSetId, + RunnerScaleSetId: runnerScaleSetID, GitHubConfigUrl: autoscalingRunnerSet.Spec.GitHubConfigUrl, GitHubConfigSecret: autoscalingRunnerSet.Spec.GitHubConfigSecret, Proxy: autoscalingRunnerSet.Spec.Proxy, @@ -556,20 +555,12 @@ func (b *ResourceBuilder) newEphemeralRunnerSet(autoscalingRunnerSet *v1alpha1.A } func (b *ResourceBuilder) newEphemeralRunner(ephemeralRunnerSet *v1alpha1.EphemeralRunnerSet) *v1alpha1.EphemeralRunner { - labels := make(map[string]string) - for k, v := range ephemeralRunnerSet.Labels { - if k == LabelKeyKubernetesComponent { - labels[k] = "runner" - } else { - labels[k] = v - } - } - - annotations := make(map[string]string) - for key, val := range ephemeralRunnerSet.Annotations { - annotations[key] = val - } + labels := make(map[string]string, len(ephemeralRunnerSet.Labels)) + maps.Copy(labels, ephemeralRunnerSet.Labels) + labels[LabelKeyKubernetesComponent] = "runner" + annotations := make(map[string]string, len(ephemeralRunnerSet.Annotations)+1) + maps.Copy(annotations, ephemeralRunnerSet.Annotations) annotations[AnnotationKeyPatchID] = strconv.Itoa(ephemeralRunnerSet.Spec.PatchID) return &v1alpha1.EphemeralRunner{ ObjectMeta: metav1.ObjectMeta{ @@ -596,27 +587,17 @@ func (b *ResourceBuilder) newEphemeralRunner(ephemeralRunnerSet *v1alpha1.Epheme } } -func (b *ResourceBuilder) newEphemeralRunnerPod(ctx context.Context, runner *v1alpha1.EphemeralRunner, secret *corev1.Secret, envs ...corev1.EnvVar) *corev1.Pod { +func (b *ResourceBuilder) newEphemeralRunnerPod(runner *v1alpha1.EphemeralRunner, secret *corev1.Secret, envs ...corev1.EnvVar) *corev1.Pod { var newPod corev1.Pod - labels := map[string]string{} - annotations := map[string]string{} + annotations := make(map[string]string, len(runner.Annotations)+len(runner.Spec.Annotations)) + maps.Copy(annotations, runner.Annotations) + maps.Copy(annotations, runner.Spec.Annotations) - for k, v := range runner.Labels { - labels[k] = v - } - for k, v := range runner.Spec.Labels { - labels[k] = v - } + labels := make(map[string]string, len(runner.Labels)+len(runner.Spec.Labels)+2) + maps.Copy(labels, runner.Labels) + maps.Copy(labels, runner.Spec.Labels) labels["actions-ephemeral-runner"] = string(corev1.ConditionTrue) - - for k, v := range runner.Annotations { - annotations[k] = v - } - for k, v := range runner.Spec.Annotations { - annotations[k] = v - } - labels[LabelKeyPodTemplateHash] = hash.FNVHashStringObjects( FilterLabels(labels, LabelKeyRunnerTemplateHash), annotations, diff --git a/controllers/actions.github.com/resourcebuilder_test.go b/controllers/actions.github.com/resourcebuilder_test.go index 12e50533..b4c11466 100644 --- a/controllers/actions.github.com/resourcebuilder_test.go +++ b/controllers/actions.github.com/resourcebuilder_test.go @@ -1,7 +1,6 @@ package actionsgithubcom import ( - "context" "fmt" "strings" "testing" @@ -28,7 +27,7 @@ func TestLabelPropagation(t *testing.T) { "directly.excluded.org/arbitrary": "not-excluded-value", }, Annotations: map[string]string{ - runnerScaleSetIdAnnotationKey: "1", + runnerScaleSetIDAnnotationKey: "1", AnnotationKeyGitHubRunnerGroupName: "test-group", AnnotationKeyGitHubRunnerScaleSetName: "test-scale-set", }, @@ -104,7 +103,7 @@ func TestLabelPropagation(t *testing.T) { Name: "test", }, } - pod := b.newEphemeralRunnerPod(context.TODO(), ephemeralRunner, runnerSecret) + pod := b.newEphemeralRunnerPod(ephemeralRunner, runnerSecret) for key := range ephemeralRunner.Labels { assert.Equal(t, ephemeralRunner.Labels[key], pod.Labels[key]) } @@ -124,7 +123,7 @@ func TestGitHubURLTrimLabelValues(t *testing.T) { LabelKeyKubernetesVersion: "0.2.0", }, Annotations: map[string]string{ - runnerScaleSetIdAnnotationKey: "1", + runnerScaleSetIDAnnotationKey: "1", AnnotationKeyGitHubRunnerGroupName: "test-group", AnnotationKeyGitHubRunnerScaleSetName: "test-scale-set", }, @@ -190,7 +189,7 @@ func TestOwnershipRelationships(t *testing.T) { LabelKeyKubernetesVersion: "0.2.0", }, Annotations: map[string]string{ - runnerScaleSetIdAnnotationKey: "1", + runnerScaleSetIDAnnotationKey: "1", AnnotationKeyGitHubRunnerGroupName: "test-group", AnnotationKeyGitHubRunnerScaleSetName: "test-scale-set", annotationKeyValuesHash: "test-hash", @@ -233,7 +232,7 @@ func TestOwnershipRelationships(t *testing.T) { Name: "test-secret", }, } - pod := b.newEphemeralRunnerPod(context.TODO(), ephemeralRunner, runnerSecret) + pod := b.newEphemeralRunnerPod(ephemeralRunner, runnerSecret) // Test EphemeralRunnerPod ownership require.Len(t, pod.OwnerReferences, 1, "EphemeralRunnerPod should have exactly one owner reference") From 837406ae015ec70961e2093510a9a9c3826bbf33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 14:49:28 +0100 Subject: [PATCH 6/8] Bump the gomod group across 1 directory with 11 updates (#4317) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nikola Jokic --- go.mod | 37 +++++++++++++-------------- go.sum | 80 ++++++++++++++++++++++++++++------------------------------ 2 files changed, 56 insertions(+), 61 deletions(-) diff --git a/go.mod b/go.mod index c6dfbbd4..d6c26b05 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/actions/actions-runner-controller go 1.25.1 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azsecrets v1.4.0 github.com/bradleyfalzon/ghinstallation/v2 v2.17.0 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc @@ -16,27 +16,27 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/mux v1.8.1 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 - github.com/gruntwork-io/terratest v0.51.0 + github.com/gruntwork-io/terratest v0.53.0 github.com/hashicorp/go-retryablehttp v0.7.8 github.com/kelseyhightower/envconfig v1.4.0 github.com/onsi/ginkgo v1.16.5 - github.com/onsi/ginkgo/v2 v2.26.0 + github.com/onsi/ginkgo/v2 v2.27.2 github.com/onsi/gomega v1.38.2 github.com/prometheus/client_golang v1.23.2 github.com/stretchr/testify v1.11.1 github.com/teambition/rrule-go v1.8.2 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/net v0.46.0 - golang.org/x/oauth2 v0.32.0 - golang.org/x/sync v0.17.0 + golang.org/x/net v0.47.0 + golang.org/x/oauth2 v0.33.0 + golang.org/x/sync v0.18.0 gomodules.xyz/jsonpatch/v2 v2.5.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.34.1 - k8s.io/apimachinery v0.34.1 - k8s.io/client-go v0.34.1 + k8s.io/api v0.34.2 + k8s.io/apimachinery v0.34.2 + k8s.io/client-go v0.34.2 k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 - sigs.k8s.io/controller-runtime v0.22.3 + sigs.k8s.io/controller-runtime v0.22.4 sigs.k8s.io/yaml v1.6.0 ) @@ -44,7 +44,7 @@ require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect github.com/BurntSushi/toml v1.5.0 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/ProtonMail/go-crypto v1.3.0 // indirect @@ -163,17 +163,16 @@ require ( github.com/virtuald/go-ordered-json v0.0.0-20170621173500-b18e6e673d74 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect - go.uber.org/automaxprocs v1.6.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.43.0 // indirect + golang.org/x/crypto v0.44.0 // indirect golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/term v0.36.0 // indirect - golang.org/x/text v0.30.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.13.0 // indirect - golang.org/x/tools v0.37.0 // indirect + golang.org/x/tools v0.38.0 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index 3525fc9b..3ab8ea20 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,10 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/Azure/azure-sdk-for-go v51.0.0+incompatible h1:p7blnyJSjJqf5jflHbSGhIhEpXIgIFmYZNg5uwqweso= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0 h1:KpMC6LFL7mqpExyMC9jVOYRiVhLmamjeZfRsUpB7l4s= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= @@ -15,8 +15,8 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfg github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI= -github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= +github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= @@ -134,8 +134,8 @@ github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BN github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= -github.com/gkampitakis/go-snaps v0.5.14 h1:3fAqdB6BCPKHDMHAKRwtPUwYexKtGrNuw8HX/T/4neo= -github.com/gkampitakis/go-snaps v0.5.14/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= +github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= +github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= @@ -233,8 +233,8 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/gruntwork-io/go-commons v0.17.2 h1:14dsCJ7M5Vv2X3BIPKeG9Kdy6vTMGhM8L4WZazxfTuY= github.com/gruntwork-io/go-commons v0.17.2/go.mod h1:zs7Q2AbUKuTarBPy19CIxJVUX/rBamfW8IwuWKniWkE= -github.com/gruntwork-io/terratest v0.51.0 h1:RCXlCwWlHqhUoxgF6n3hvywvbvrsTXqoqt34BrnLekw= -github.com/gruntwork-io/terratest v0.51.0/go.mod h1:evZHXb8VWDgv5O5zEEwfkwMhkx9I53QR/RB11cISrpg= +github.com/gruntwork-io/terratest v0.53.0 h1:r5U3nfrQCTGvnlJIIh6R5g8z8dwRcjNESYO/wYyOXsI= +github.com/gruntwork-io/terratest v0.53.0/go.mod h1:y2Evi+Ac04QpzF3mbRPqrBjipDN7gjqlw6+OZoy2vX4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -316,8 +316,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.26.0 h1:1J4Wut1IlYZNEAWIV3ALrT9NfiaGW2cDCJQSFQMs/gE= -github.com/onsi/ginkgo/v2 v2.26.0/go.mod h1:qhEywmzWTBUY88kfO0BRvX4py7scov9yR+Az2oavUzw= +github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= +github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= @@ -331,8 +331,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pquerna/otp v1.5.0 h1:NMMR+WrmaqXU4EzdGJEE1aUUI0AMRzsp96fFFWNPwxs= github.com/pquerna/otp v1.5.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= -github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= -github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= @@ -380,8 +378,6 @@ github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAz github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= -go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= @@ -395,30 +391,30 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -430,14 +426,14 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI= golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -445,8 +441,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -479,22 +475,22 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM= -k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk= +k8s.io/api v0.34.2 h1:fsSUNZhV+bnL6Aqrp6O7lMTy6o5x2C4XLjnh//8SLYY= +k8s.io/api v0.34.2/go.mod h1:MMBPaWlED2a8w4RSeanD76f7opUoypY8TFYkSM+3XHw= k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI= k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc= -k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4= -k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY= -k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8= +k8s.io/apimachinery v0.34.2 h1:zQ12Uk3eMHPxrsbUJgNF8bTauTVR2WgqJsTmwTE/NW4= +k8s.io/apimachinery v0.34.2/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +k8s.io/client-go v0.34.2 h1:Co6XiknN+uUZqiddlfAjT68184/37PS4QAzYvQvDR8M= +k8s.io/client-go v0.34.2/go.mod h1:2VYDl1XXJsdcAxw7BenFslRQX28Dxz91U9MWKjX97fE= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.22.3 h1:I7mfqz/a/WdmDCEnXmSPm8/b/yRTy6JsKKENTijTq8Y= -sigs.k8s.io/controller-runtime v0.22.3/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8= +sigs.k8s.io/controller-runtime v0.22.4 h1:GEjV7KV3TY8e+tJ2LCTxUTanW4z/FmNB7l327UfMq9A= +sigs.k8s.io/controller-runtime v0.22.4/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= From cac7a40b70a25b27245dc7ddba5d7a49d4427201 Mon Sep 17 00:00:00 2001 From: Marcus Ramberg Date: Fri, 21 Nov 2025 14:56:08 +0000 Subject: [PATCH 7/8] Add support for giving kubernetes mode scaleset service account additional permissions (#4282) --- .../templates/kube_mode_role.yaml | 33 ++++++++++--------- .../tests/values_k8s_extra_role_rules.yaml | 30 +++++++++++++++++ charts/gha-runner-scale-set/values.yaml | 1 + 3 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 charts/gha-runner-scale-set/tests/values_k8s_extra_role_rules.yaml diff --git a/charts/gha-runner-scale-set/templates/kube_mode_role.yaml b/charts/gha-runner-scale-set/templates/kube_mode_role.yaml index 9e53062f..f34d78bb 100644 --- a/charts/gha-runner-scale-set/templates/kube_mode_role.yaml +++ b/charts/gha-runner-scale-set/templates/kube_mode_role.yaml @@ -36,21 +36,24 @@ metadata: finalizers: - actions.github.com/cleanup-protection rules: -- apiGroups: [""] - resources: ["pods"] - verbs: ["get", "list", "create", "delete"] -- apiGroups: [""] - resources: ["pods/exec"] - verbs: ["get", "create"] -- apiGroups: [""] - resources: ["pods/log"] - verbs: ["get", "list", "watch",] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "create", "delete"] + - apiGroups: [""] + resources: ["pods/exec"] + verbs: ["get", "create"] + - apiGroups: [""] + resources: ["pods/log"] + verbs: ["get", "list", "watch",] {{- if ne $containerMode.type "kubernetes-novolume" }} -- apiGroups: ["batch"] - resources: ["jobs"] - verbs: ["get", "list", "create", "delete"] + - apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "create", "delete"] +{{- end }} + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "create", "delete"] +{{- with $containerMode.kubernetesModeAdditionalRoleRules}} +{{- toYaml . | nindent 2}} {{- end }} -- apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list", "create", "delete"] {{- end }} diff --git a/charts/gha-runner-scale-set/tests/values_k8s_extra_role_rules.yaml b/charts/gha-runner-scale-set/tests/values_k8s_extra_role_rules.yaml new file mode 100644 index 00000000..588f8973 --- /dev/null +++ b/charts/gha-runner-scale-set/tests/values_k8s_extra_role_rules.yaml @@ -0,0 +1,30 @@ +githubConfigUrl: https://github.com/actions/actions-runner-controller +githubConfigSecret: + github_token: test +template: + spec: + containers: + - name: other + image: other-image:latest + volumes: + - name: foo + emptyDir: {} + - name: bar + emptyDir: {} + - name: work + hostPath: + path: /data + type: Directory +containerMode: + type: kubernetes + kubernetesModeAdditionalRoleRule: + - apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - create + - delete + diff --git a/charts/gha-runner-scale-set/values.yaml b/charts/gha-runner-scale-set/values.yaml index 5a0f4ca3..8a9b64e9 100644 --- a/charts/gha-runner-scale-set/values.yaml +++ b/charts/gha-runner-scale-set/values.yaml @@ -124,6 +124,7 @@ githubConfigSecret: # resources: # requests: # storage: 1Gi +# kubernetesModeAdditionalRoleRules: [] # ## listenerTemplate is the PodSpec for each listener Pod From fdf78189abac04ffa4e07538350f9a5547aaf11e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 17:14:05 +0100 Subject: [PATCH 8/8] Bump golang.org/x/crypto from 0.43.0 to 0.45.0 (#4318) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nikola Jokic --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d6c26b05..e6a0caf2 100644 --- a/go.mod +++ b/go.mod @@ -165,7 +165,7 @@ require ( github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.44.0 // indirect + golang.org/x/crypto v0.45.0 // indirect golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 // indirect golang.org/x/mod v0.29.0 // indirect golang.org/x/sys v0.38.0 // indirect diff --git a/go.sum b/go.sum index 3ab8ea20..15ca5b58 100644 --- a/go.sum +++ b/go.sum @@ -391,8 +391,8 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= +golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9 h1:TQwNpfvNkxAVlItJf6Cr5JTsVZoC/Sj7K3OZv2Pc14A= golang.org/x/exp v0.0.0-20251002181428-27f1f14c8bb9/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=