diff --git a/.github/workflows/arc-publish-chart.yaml b/.github/workflows/arc-publish-chart.yaml deleted file mode 100644 index 96f03f22..00000000 --- a/.github/workflows/arc-publish-chart.yaml +++ /dev/null @@ -1,212 +0,0 @@ -name: Publish ARC Helm Charts - -# Revert to https://github.com/actions-runner-controller/releases#releases -# for details on why we use this approach -on: - push: - branches: - - master - paths: - - 'charts/**' - - '.github/workflows/arc-publish-chart.yaml' - - '!charts/actions-runner-controller/docs/**' - - '!charts/gha-runner-scale-set-controller/**' - - '!charts/gha-runner-scale-set/**' - - '!**.md' - workflow_dispatch: - inputs: - force: - description: 'Force publish even if the chart version is not bumped' - type: boolean - required: true - default: false - -env: - KUBE_SCORE_VERSION: 1.10.0 - HELM_VERSION: v3.8.0 - -permissions: - contents: write - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: true - -jobs: - lint-chart: - name: Lint Chart - runs-on: ubuntu-latest - outputs: - publish-chart: ${{ steps.publish-chart-step.outputs.publish }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Helm - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 - with: - version: ${{ env.HELM_VERSION }} - - - name: Set up kube-score - run: | - wget https://github.com/zegl/kube-score/releases/download/v${{ env.KUBE_SCORE_VERSION }}/kube-score_${{ env.KUBE_SCORE_VERSION }}_linux_amd64 -O kube-score - chmod 755 kube-score - - - name: Kube-score generated manifests - run: helm template --values charts/.ci/values-kube-score.yaml charts/* | ./kube-score score - --ignore-test pod-networkpolicy --ignore-test deployment-has-poddisruptionbudget --ignore-test deployment-has-host-podantiaffinity --ignore-test container-security-context --ignore-test pod-probes --ignore-test container-image-tag --enable-optional-test container-security-context-privileged --enable-optional-test container-security-context-readonlyrootfilesystem - - # python is a requirement for the chart-testing action below (supports yamllint among other tests) - - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Set up chart-testing - uses: helm/chart-testing-action@v2.6.0 - - - name: Run chart-testing (list-changed) - id: list-changed - run: | - changed=$(ct list-changed --config charts/.ci/ct-config.yaml) - if [[ -n "$changed" ]]; then - echo "changed=true" >> $GITHUB_OUTPUT - fi - - - name: Run chart-testing (lint) - run: | - ct lint --config charts/.ci/ct-config.yaml - - - name: Create kind cluster - if: steps.list-changed.outputs.changed == 'true' - uses: helm/kind-action@v1.4.0 - - # We need cert-manager already installed in the cluster because we assume the CRDs exist - - name: Install cert-manager - if: steps.list-changed.outputs.changed == 'true' - run: | - helm repo add jetstack https://charts.jetstack.io --force-update - helm install cert-manager jetstack/cert-manager --set installCRDs=true --wait - - - name: Run chart-testing (install) - if: steps.list-changed.outputs.changed == 'true' - run: ct install --config charts/.ci/ct-config.yaml - - # WARNING: This relies on the latest release being at the top of the JSON from GitHub and a clean chart.yaml - - name: Check if Chart Publish is Needed - id: publish-chart-step - run: | - CHART_TEXT=$(curl -fs https://raw.githubusercontent.com/${{ github.repository }}/master/charts/actions-runner-controller/Chart.yaml) - NEW_CHART_VERSION=$(echo "$CHART_TEXT" | grep version: | cut -d ' ' -f 2) - RELEASE_LIST=$(curl -fs https://api.github.com/repos/${{ github.repository }}/releases | jq .[].tag_name | grep actions-runner-controller | cut -d '"' -f 2 | cut -d '-' -f 4) - LATEST_RELEASED_CHART_VERSION=$(echo $RELEASE_LIST | cut -d ' ' -f 1) - - echo "CHART_VERSION_IN_MASTER=$NEW_CHART_VERSION" >> $GITHUB_ENV - echo "LATEST_CHART_VERSION=$LATEST_RELEASED_CHART_VERSION" >> $GITHUB_ENV - - # Always publish if force is true - if [[ $NEW_CHART_VERSION != $LATEST_RELEASED_CHART_VERSION || "${{ inputs.force }}" == "true" ]]; then - echo "publish=true" >> $GITHUB_OUTPUT - else - echo "publish=false" >> $GITHUB_OUTPUT - fi - - - name: Job summary - run: | - echo "Chart linting has been completed." >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Status:**" >> $GITHUB_STEP_SUMMARY - echo "- chart version in master: ${{ env.CHART_VERSION_IN_MASTER }}" >> $GITHUB_STEP_SUMMARY - echo "- latest chart version: ${{ env.LATEST_CHART_VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- publish new chart: ${{ steps.publish-chart-step.outputs.publish }}" >> $GITHUB_STEP_SUMMARY - - publish-chart: - if: needs.lint-chart.outputs.publish-chart == 'true' - needs: lint-chart - name: Publish Chart - runs-on: ubuntu-latest - permissions: - contents: write # for helm/chart-releaser-action to push chart release and create a release - env: - CHART_TARGET_ORG: actions-runner-controller - CHART_TARGET_REPO: actions-runner-controller.github.io - CHART_TARGET_BRANCH: master - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Configure Git - run: | - git config user.name "$GITHUB_ACTOR" - git config user.email "$GITHUB_ACTOR@users.noreply.github.com" - - - name: Get Token - id: get_workflow_token - uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 - with: - application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }} - application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }} - organization: ${{ env.CHART_TARGET_ORG }} - - - name: Install chart-releaser - uses: helm/chart-releaser-action@v1.4.1 - with: - install_only: true - install_dir: ${{ github.workspace }}/bin - - - name: Package and upload release assets - run: | - cr package \ - ${{ github.workspace }}/charts/actions-runner-controller/ \ - --package-path .cr-release-packages - - cr upload \ - --owner "$(echo ${{ github.repository }} | cut -d '/' -f 1)" \ - --git-repo "$(echo ${{ github.repository }} | cut -d '/' -f 2)" \ - --package-path .cr-release-packages \ - --token ${{ secrets.GITHUB_TOKEN }} - - - name: Generate updated index.yaml - run: | - cr index \ - --owner "$(echo ${{ github.repository }} | cut -d '/' -f 1)" \ - --git-repo "$(echo ${{ github.repository }} | cut -d '/' -f 2)" \ - --index-path ${{ github.workspace }}/index.yaml \ - --token ${{ secrets.GITHUB_TOKEN }} \ - --push \ - --pages-branch 'gh-pages' \ - --pages-index-path 'index.yaml' - - # Chart Release was never intended to publish to a different repo - # this workaround is intended to move the index.yaml to the target repo - # where the github pages are hosted - - name: Checkout target repository - uses: actions/checkout@v4 - with: - repository: ${{ env.CHART_TARGET_ORG }}/${{ env.CHART_TARGET_REPO }} - path: ${{ env.CHART_TARGET_REPO }} - ref: ${{ env.CHART_TARGET_BRANCH }} - token: ${{ steps.get_workflow_token.outputs.token }} - - - name: Copy index.yaml - run: | - cp ${{ github.workspace }}/index.yaml ${{ env.CHART_TARGET_REPO }}/actions-runner-controller/index.yaml - - - name: Commit and push to target repository - run: | - git config user.name "$GITHUB_ACTOR" - git config user.email "$GITHUB_ACTOR@users.noreply.github.com" - git add . - git commit -m "Update index.yaml" - git push - working-directory: ${{ github.workspace }}/${{ env.CHART_TARGET_REPO }} - - - name: Job summary - run: | - echo "New helm chart has been published" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Status:**" >> $GITHUB_STEP_SUMMARY - echo "- New [index.yaml](https://github.com/${{ env.CHART_TARGET_ORG }}/${{ env.CHART_TARGET_REPO }}/tree/master/actions-runner-controller) pushed" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/arc-publish.yaml b/.github/workflows/arc-publish.yaml deleted file mode 100644 index 37d67e9f..00000000 --- a/.github/workflows/arc-publish.yaml +++ /dev/null @@ -1,109 +0,0 @@ -name: Publish ARC Image - -# Revert to https://github.com/actions-runner-controller/releases#releases -# for details on why we use this approach -on: - release: - types: - - published - workflow_dispatch: - inputs: - release_tag_name: - description: 'Tag name of the release to publish' - required: true - push_to_registries: - description: 'Push images to registries' - required: true - type: boolean - default: false - -permissions: - contents: write - packages: write - -env: - TARGET_ORG: actions-runner-controller - TARGET_REPO: actions-runner-controller - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: true - -jobs: - release-controller: - name: Release - runs-on: ubuntu-latest - # gha-runner-scale-set has its own release workflow. - # We don't want to publish a new actions-runner-controller image - # we release gha-runner-scale-set. - if: ${{ !startsWith(github.event.inputs.release_tag_name, 'gha-runner-scale-set-') }} - steps: - - name: Checkout - uses: actions/checkout@v4 - - - uses: actions/setup-go@v5 - with: - go-version-file: 'go.mod' - - - name: Install tools - run: | - curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.2.0/kubebuilder_2.2.0_linux_amd64.tar.gz - tar zxvf kubebuilder_2.2.0_linux_amd64.tar.gz - sudo mv kubebuilder_2.2.0_linux_amd64 /usr/local/kubebuilder - curl -s https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh | bash - sudo mv kustomize /usr/local/bin - curl -L -O https://github.com/tcnksm/ghr/releases/download/v0.13.0/ghr_v0.13.0_linux_amd64.tar.gz - tar zxvf ghr_v0.13.0_linux_amd64.tar.gz - sudo mv ghr_v0.13.0_linux_amd64/ghr /usr/local/bin - - - name: Set version env variable - run: | - # Define the release tag name based on the event type - if [[ "${{ github.event_name }}" == "release" ]]; then - echo "VERSION=$(cat ${GITHUB_EVENT_PATH} | jq -r '.release.tag_name')" >> $GITHUB_ENV - elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - echo "VERSION=${{ inputs.release_tag_name }}" >> $GITHUB_ENV - fi - - - name: Upload artifacts - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - make github-release - - - name: Get Token - id: get_workflow_token - uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 - with: - application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }} - application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }} - organization: ${{ env.TARGET_ORG }} - - - name: Resolve push to registries - run: | - # Define the push to registries based on the event type - if [[ "${{ github.event_name }}" == "release" ]]; then - echo "PUSH_TO_REGISTRIES=true" >> $GITHUB_ENV - elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - echo "PUSH_TO_REGISTRIES=${{ inputs.push_to_registries }}" >> $GITHUB_ENV - fi - - - name: Trigger Build And Push Images To Registries - run: | - # Authenticate - gh auth login --with-token <<< ${{ steps.get_workflow_token.outputs.token }} - - # Trigger the workflow run - jq -n '{"event_type": "arc", "client_payload": {"release_tag_name": "${{ env.VERSION }}", "push_to_registries": "${{ env.PUSH_TO_REGISTRIES }}" }}' \ - | gh api -X POST /repos/actions-runner-controller/releases/dispatches --input - - - - name: Job summary - run: | - echo "The [publish-arc](https://github.com/actions-runner-controller/releases/blob/main/.github/workflows/publish-arc.yaml) workflow has been triggered!" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY - echo "- Release tag: ${{ env.VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- Push to registries: ${{ env.PUSH_TO_REGISTRIES }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Status:**" >> $GITHUB_STEP_SUMMARY - echo "[https://github.com/actions-runner-controller/releases/actions/workflows/publish-arc.yaml](https://github.com/actions-runner-controller/releases/actions/workflows/publish-arc.yaml)" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/arc-release-runners.yaml b/.github/workflows/arc-release-runners.yaml deleted file mode 100644 index 55ced306..00000000 --- a/.github/workflows/arc-release-runners.yaml +++ /dev/null @@ -1,79 +0,0 @@ -name: Release ARC Runner Images - -# Revert to https://github.com/actions-runner-controller/releases#releases -# for details on why we use this approach -on: - # We must do a trigger on a push: instead of a types: closed so GitHub Secrets - # are available to the workflow run - push: - branches: - - 'master' - paths: - - 'runner/VERSION' - - '.github/workflows/arc-release-runners.yaml' - -env: - # Safeguard to prevent pushing images to registeries after build - PUSH_TO_REGISTRIES: true - TARGET_ORG: actions-runner-controller - TARGET_WORKFLOW: release-runners.yaml - DOCKER_VERSION: 24.0.7 - -concurrency: - group: ${{ github.workflow }} - cancel-in-progress: true - -jobs: - build-runners: - name: Trigger Build and Push of Runner Images - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Get runner version - id: versions - run: | - runner_current_version="$(echo -n $(cat runner/VERSION | grep 'RUNNER_VERSION=' | cut -d '=' -f2))" - container_hooks_current_version="$(echo -n $(cat runner/VERSION | grep 'RUNNER_CONTAINER_HOOKS_VERSION=' | cut -d '=' -f2))" - echo runner_version=$runner_current_version >> $GITHUB_OUTPUT - echo container_hooks_version=$container_hooks_current_version >> $GITHUB_OUTPUT - - - name: Get Token - id: get_workflow_token - uses: peter-murray/workflow-application-token-action@dc0413987a085fa17d19df9e47d4677cf81ffef3 - with: - application_id: ${{ secrets.ACTIONS_ACCESS_APP_ID }} - application_private_key: ${{ secrets.ACTIONS_ACCESS_PK }} - organization: ${{ env.TARGET_ORG }} - - - name: Trigger Build And Push Runner Images To Registries - env: - RUNNER_VERSION: ${{ steps.versions.outputs.runner_version }} - CONTAINER_HOOKS_VERSION: ${{ steps.versions.outputs.container_hooks_version }} - run: | - # Authenticate - gh auth login --with-token <<< ${{ steps.get_workflow_token.outputs.token }} - - # Trigger the workflow run - gh workflow run ${{ env.TARGET_WORKFLOW }} -R ${{ env.TARGET_ORG }}/releases \ - -f runner_version=${{ env.RUNNER_VERSION }} \ - -f docker_version=${{ env.DOCKER_VERSION }} \ - -f runner_container_hooks_version=${{ env.CONTAINER_HOOKS_VERSION }} \ - -f sha='${{ github.sha }}' \ - -f push_to_registries=${{ env.PUSH_TO_REGISTRIES }} - - - name: Job summary - env: - RUNNER_VERSION: ${{ steps.versions.outputs.runner_version }} - CONTAINER_HOOKS_VERSION: ${{ steps.versions.outputs.container_hooks_version }} - run: | - echo "The [release-runners.yaml](https://github.com/actions-runner-controller/releases/blob/main/.github/workflows/release-runners.yaml) workflow has been triggered!" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Parameters:**" >> $GITHUB_STEP_SUMMARY - echo "- runner_version: ${{ env.RUNNER_VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- docker_version: ${{ env.DOCKER_VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- runner_container_hooks_version: ${{ env.CONTAINER_HOOKS_VERSION }}" >> $GITHUB_STEP_SUMMARY - echo "- sha: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY - echo "- push_to_registries: ${{ env.PUSH_TO_REGISTRIES }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**Status:**" >> $GITHUB_STEP_SUMMARY - echo "[https://github.com/actions-runner-controller/releases/actions/workflows/release-runners.yaml](https://github.com/actions-runner-controller/releases/actions/workflows/release-runners.yaml)" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/arc-update-runners-scheduled.yaml b/.github/workflows/arc-update-runners-scheduled.yaml deleted file mode 100644 index 5c540531..00000000 --- a/.github/workflows/arc-update-runners-scheduled.yaml +++ /dev/null @@ -1,153 +0,0 @@ -# This workflows polls releases from actions/runner and in case of a new one it -# updates files containing runner version and opens a pull request. -name: Runner Updates Check (Scheduled Job) - -on: - schedule: - # run daily - - cron: "0 9 * * *" - workflow_dispatch: - -jobs: - # check_versions compares our current version and the latest available runner - # version and sets them as outputs. - check_versions: - runs-on: ubuntu-latest - env: - GH_TOKEN: ${{ github.token }} - outputs: - runner_current_version: ${{ steps.runner_versions.outputs.runner_current_version }} - runner_latest_version: ${{ steps.runner_versions.outputs.runner_latest_version }} - container_hooks_current_version: ${{ steps.container_hooks_versions.outputs.container_hooks_current_version }} - container_hooks_latest_version: ${{ steps.container_hooks_versions.outputs.container_hooks_latest_version }} - steps: - - uses: actions/checkout@v4 - - - name: Get runner current and latest versions - id: runner_versions - run: | - CURRENT_VERSION="$(echo -n $(cat runner/VERSION | grep 'RUNNER_VERSION=' | cut -d '=' -f2))" - echo "Current version: $CURRENT_VERSION" - echo runner_current_version=$CURRENT_VERSION >> $GITHUB_OUTPUT - - LATEST_VERSION=$(gh release list --exclude-drafts --exclude-pre-releases --limit 1 -R actions/runner | grep -oP '(?<=v)[0-9.]+' | head -1) - echo "Latest version: $LATEST_VERSION" - echo runner_latest_version=$LATEST_VERSION >> $GITHUB_OUTPUT - - - name: Get container-hooks current and latest versions - id: container_hooks_versions - run: | - CURRENT_VERSION="$(echo -n $(cat runner/VERSION | grep 'RUNNER_CONTAINER_HOOKS_VERSION=' | cut -d '=' -f2))" - echo "Current version: $CURRENT_VERSION" - echo container_hooks_current_version=$CURRENT_VERSION >> $GITHUB_OUTPUT - - LATEST_VERSION=$(gh release list --exclude-drafts --exclude-pre-releases --limit 1 -R actions/runner-container-hooks | grep -oP '(?<=v)[0-9.]+' | head -1) - echo "Latest version: $LATEST_VERSION" - echo container_hooks_latest_version=$LATEST_VERSION >> $GITHUB_OUTPUT - - # check_pr checks if a PR for the same update already exists. It only runs if - # runner latest version != our current version. If no existing PR is found, - # it sets a PR name as output. - check_pr: - runs-on: ubuntu-latest - needs: check_versions - if: needs.check_versions.outputs.runner_current_version != needs.check_versions.outputs.runner_latest_version || needs.check_versions.outputs.container_hooks_current_version != needs.check_versions.outputs.container_hooks_latest_version - outputs: - pr_name: ${{ steps.pr_name.outputs.pr_name }} - env: - GH_TOKEN: ${{ github.token }} - steps: - - name: debug - run: - echo "RUNNER_CURRENT_VERSION=${{ needs.check_versions.outputs.runner_current_version }}" - echo "RUNNER_LATEST_VERSION=${{ needs.check_versions.outputs.runner_latest_version }}" - echo "CONTAINER_HOOKS_CURRENT_VERSION=${{ needs.check_versions.outputs.container_hooks_current_version }}" - echo "CONTAINER_HOOKS_LATEST_VERSION=${{ needs.check_versions.outputs.container_hooks_latest_version }}" - - - uses: actions/checkout@v4 - - - name: PR Name - id: pr_name - env: - RUNNER_CURRENT_VERSION: ${{ needs.check_versions.outputs.runner_current_version }} - RUNNER_LATEST_VERSION: ${{ needs.check_versions.outputs.runner_latest_version }} - CONTAINER_HOOKS_CURRENT_VERSION: ${{ needs.check_versions.outputs.container_hooks_current_version }} - CONTAINER_HOOKS_LATEST_VERSION: ${{ needs.check_versions.outputs.container_hooks_latest_version }} - # Generate a PR name with the following title: - # Updates: runner to v2.304.0 and container-hooks to v0.3.1 - run: | - RUNNER_MESSAGE="runner to v${RUNNER_LATEST_VERSION}" - CONTAINER_HOOKS_MESSAGE="container-hooks to v${CONTAINER_HOOKS_LATEST_VERSION}" - - PR_NAME="Updates:" - if [ "$RUNNER_CURRENT_VERSION" != "$RUNNER_LATEST_VERSION" ] - then - PR_NAME="$PR_NAME $RUNNER_MESSAGE" - fi - if [ "$CONTAINER_HOOKS_CURRENT_VERSION" != "$CONTAINER_HOOKS_LATEST_VERSION" ] - then - PR_NAME="$PR_NAME $CONTAINER_HOOKS_MESSAGE" - fi - - result=$(gh pr list --search "$PR_NAME" --json number --jq ".[].number" --limit 1) - if [ -z "$result" ] - then - echo "No existing PRs found, setting output with pr_name=$PR_NAME" - echo pr_name=$PR_NAME >> $GITHUB_OUTPUT - else - echo "Found a PR with title '$PR_NAME' already existing: ${{ github.server_url }}/${{ github.repository }}/pull/$result" - fi - - # update_version updates runner version in the files listed below, commits - # the changes and opens a pull request as `github-actions` bot. - update_version: - runs-on: ubuntu-latest - needs: - - check_versions - - check_pr - if: needs.check_pr.outputs.pr_name - permissions: - pull-requests: write - contents: write - actions: write - env: - GH_TOKEN: ${{ github.token }} - RUNNER_CURRENT_VERSION: ${{ needs.check_versions.outputs.runner_current_version }} - RUNNER_LATEST_VERSION: ${{ needs.check_versions.outputs.runner_latest_version }} - CONTAINER_HOOKS_CURRENT_VERSION: ${{ needs.check_versions.outputs.container_hooks_current_version }} - CONTAINER_HOOKS_LATEST_VERSION: ${{ needs.check_versions.outputs.container_hooks_latest_version }} - PR_NAME: ${{ needs.check_pr.outputs.pr_name }} - - steps: - - uses: actions/checkout@v4 - - - name: New branch - run: git checkout -b update-runner-"$(date +%Y-%m-%d)" - - - name: Update files - run: | - CURRENT_VERSION="${RUNNER_CURRENT_VERSION//./\\.}" - LATEST_VERSION="${RUNNER_LATEST_VERSION//./\\.}" - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/VERSION - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/Makefile - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" Makefile - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" test/e2e/e2e_test.go - - CURRENT_VERSION="${CONTAINER_HOOKS_CURRENT_VERSION//./\\.}" - LATEST_VERSION="${CONTAINER_HOOKS_LATEST_VERSION//./\\.}" - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/VERSION - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" runner/Makefile - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" Makefile - sed -i "s/$CURRENT_VERSION/$LATEST_VERSION/g" test/e2e/e2e_test.go - - - name: Commit changes - run: | - # from https://github.com/orgs/community/discussions/26560 - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config user.name "github-actions[bot]" - git add . - git commit -m "$PR_NAME" - git push -u origin HEAD - - - name: Create pull request - run: gh pr create -f -l "runners update" diff --git a/.github/workflows/arc-validate-chart.yaml b/.github/workflows/arc-validate-chart.yaml deleted file mode 100644 index f38a3fc3..00000000 --- a/.github/workflows/arc-validate-chart.yaml +++ /dev/null @@ -1,103 +0,0 @@ -name: Validate Helm Chart - -on: - pull_request: - branches: - - master - paths: - - 'charts/**' - - '.github/workflows/arc-validate-chart.yaml' - - '!charts/actions-runner-controller/docs/**' - - '!**.md' - - '!charts/gha-runner-scale-set-controller/**' - - '!charts/gha-runner-scale-set/**' - push: - paths: - - 'charts/**' - - '.github/workflows/arc-validate-chart.yaml' - - '!charts/actions-runner-controller/docs/**' - - '!**.md' - - '!charts/gha-runner-scale-set-controller/**' - - '!charts/gha-runner-scale-set/**' - workflow_dispatch: -env: - KUBE_SCORE_VERSION: 1.10.0 - HELM_VERSION: v3.8.0 - -permissions: - contents: read - -concurrency: - # This will make sure we only apply the concurrency limits on pull requests - # but not pushes to master branch by making the concurrency group name unique - # for pushes - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - validate-chart: - name: Lint Chart - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Helm - # Using https://github.com/Azure/setup-helm/releases/tag/v4.2 - uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 - with: - version: ${{ env.HELM_VERSION }} - - - name: Set up kube-score - run: | - wget https://github.com/zegl/kube-score/releases/download/v${{ env.KUBE_SCORE_VERSION }}/kube-score_${{ env.KUBE_SCORE_VERSION }}_linux_amd64 -O kube-score - chmod 755 kube-score - - - name: Kube-score generated manifests - run: helm template --values charts/.ci/values-kube-score.yaml charts/* | ./kube-score score - - --ignore-test pod-networkpolicy - --ignore-test deployment-has-poddisruptionbudget - --ignore-test deployment-has-host-podantiaffinity - --ignore-test container-security-context - --ignore-test pod-probes - --ignore-test container-image-tag - --enable-optional-test container-security-context-privileged - --enable-optional-test container-security-context-readonlyrootfilesystem - - # python is a requirement for the chart-testing action below (supports yamllint among other tests) - - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Set up chart-testing - uses: helm/chart-testing-action@v2.6.0 - - - name: Run chart-testing (list-changed) - id: list-changed - run: | - changed=$(ct list-changed --config charts/.ci/ct-config.yaml) - if [[ -n "$changed" ]]; then - echo "changed=true" >> $GITHUB_OUTPUT - fi - - - name: Run chart-testing (lint) - run: | - ct lint --config charts/.ci/ct-config.yaml - - - name: Create kind cluster - uses: helm/kind-action@v1.4.0 - if: steps.list-changed.outputs.changed == 'true' - - # We need cert-manager already installed in the cluster because we assume the CRDs exist - - name: Install cert-manager - if: steps.list-changed.outputs.changed == 'true' - run: | - helm repo add jetstack https://charts.jetstack.io --force-update - helm install cert-manager jetstack/cert-manager --set installCRDs=true --wait - - - name: Run chart-testing (install) - if: steps.list-changed.outputs.changed == 'true' - run: | - ct install --config charts/.ci/ct-config.yaml diff --git a/.github/workflows/arc-validate-runners.yaml b/.github/workflows/arc-validate-runners.yaml deleted file mode 100644 index 9d559c37..00000000 --- a/.github/workflows/arc-validate-runners.yaml +++ /dev/null @@ -1,52 +0,0 @@ -name: Validate ARC Runners - -on: - pull_request: - branches: - - '**' - paths: - - 'runner/**' - - 'test/startup/**' - - '!**.md' - -permissions: - contents: read - -concurrency: - # This will make sure we only apply the concurrency limits on pull requests - # but not pushes to master branch by making the concurrency group name unique - # for pushes - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - shellcheck: - name: runner / shellcheck - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: shellcheck - uses: reviewdog/action-shellcheck@v1 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - path: "./runner" - pattern: | - *.sh - *.bash - update-status - # Make this consistent with `make shellsheck` - shellcheck_flags: "--shell bash --source-path runner" - exclude: "./.git/*" - check_all_files_with_shebangs: "false" - # Set this to "true" once we addressed all the shellcheck findings - fail_on_error: "false" - test-runner-entrypoint: - name: Test entrypoint - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Run tests - run: | - make acceptance/runner/startup diff --git a/.github/workflows/gha-e2e-tests.yaml b/.github/workflows/gha-e2e-tests.yaml deleted file mode 100644 index 23562005..00000000 --- a/.github/workflows/gha-e2e-tests.yaml +++ /dev/null @@ -1,993 +0,0 @@ -name: (gha) E2E Tests - -on: - push: - branches: - - master - pull_request: - branches: - - master - workflow_dispatch: - -permissions: - contents: read - -env: - TARGET_ORG: actions-runner-controller - TARGET_REPO: arc_e2e_test_dummy - IMAGE_NAME: "arc-test-image" - IMAGE_VERSION: "0.10.1" - -concurrency: - # This will make sure we only apply the concurrency limits on pull requests - # but not pushes to master branch by making the concurrency group name unique - # for pushes - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - default-setup: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: "arc-test-workflow.yaml" - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Test ARC E2E - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - - single-namespace-setup: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: "arc-test-workflow.yaml" - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - kubectl create namespace arc-runners - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - --set flags.watchSingleNamespace=arc-runners \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Test ARC E2E - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - - dind-mode-setup: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: arc-test-dind-workflow.yaml - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - --set containerMode.type="dind" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Test ARC E2E - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - - kubernetes-mode-setup: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: "arc-test-kubernetes-workflow.yaml" - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - 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 - - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - kubectl wait --timeout=30s --for=condition=ready pod -n openebs -l name=openebs-localpv-provisioner - - - name: Install gha-runner-scale-set - id: install_arc - run: | - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - --set containerMode.type="kubernetes" \ - --set containerMode.kubernetesModeWorkVolumeClaim.accessModes={"ReadWriteOnce"} \ - --set containerMode.kubernetesModeWorkVolumeClaim.storageClassName="openebs-hostpath" \ - --set containerMode.kubernetesModeWorkVolumeClaim.resources.requests.storage="1Gi" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Test ARC E2E - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - - auth-proxy-setup: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: "arc-test-workflow.yaml" - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - docker run -d \ - --name squid \ - --publish 3128:3128 \ - huangtingluo/squid-proxy:latest - kubectl create namespace arc-runners - kubectl create secret generic proxy-auth \ - --namespace=arc-runners \ - --from-literal=username=github \ - --from-literal=password='actions' - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - --set proxy.https.url="http://host.minikube.internal:3128" \ - --set proxy.https.credentialSecretRef="proxy-auth" \ - --set "proxy.noProxy[0]=10.96.0.1:443" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Test ARC E2E - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - - anonymous-proxy-setup: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: "arc-test-workflow.yaml" - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - docker run -d \ - --name squid \ - --publish 3128:3128 \ - ubuntu/squid:latest - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - --set proxy.https.url="http://host.minikube.internal:3128" \ - --set "proxy.noProxy[0]=10.96.0.1:443" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Test ARC E2E - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - - self-signed-ca-setup: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: "arc-test-workflow.yaml" - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - docker run -d \ - --rm \ - --name mitmproxy \ - --publish 8080:8080 \ - -v ${{ github.workspace }}/mitmproxy:/home/mitmproxy/.mitmproxy \ - mitmproxy/mitmproxy:latest \ - mitmdump - count=0 - while true; do - if [ -f "${{ github.workspace }}/mitmproxy/mitmproxy-ca-cert.pem" ]; then - echo "CA cert generated" - cat ${{ github.workspace }}/mitmproxy/mitmproxy-ca-cert.pem - break - fi - if [ "$count" -ge 60 ]; then - echo "Timeout waiting for mitmproxy generate its CA cert" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - sudo cp ${{ github.workspace }}/mitmproxy/mitmproxy-ca-cert.pem ${{ github.workspace }}/mitmproxy/mitmproxy-ca-cert.crt - sudo chown runner ${{ github.workspace }}/mitmproxy/mitmproxy-ca-cert.crt - kubectl create namespace arc-runners - kubectl -n arc-runners create configmap ca-cert --from-file="${{ github.workspace }}/mitmproxy/mitmproxy-ca-cert.crt" - kubectl -n arc-runners get configmap ca-cert -o yaml - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - --set proxy.https.url="http://host.minikube.internal: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/" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Test ARC E2E - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - - update-strategy-tests: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: "arc-test-sleepy-matrix.yaml" - steps: - - uses: actions/checkout@v4 - with: - ref: ${{github.head_ref}} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - --set flags.updateStrategy="eventual" \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - sleep 60 - - - name: Trigger long running jobs and wait for runners to pick them up - uses: ./.github/actions/execute-assert-arc-e2e - timeout-minutes: 10 - with: - auth-token: ${{ steps.setup.outputs.token }} - repo-owner: ${{ env.TARGET_ORG }} - repo-name: ${{env.TARGET_REPO}} - workflow-file: ${{env.WORKFLOW_FILE}} - arc-name: ${{steps.install_arc.outputs.ARC_NAME}} - arc-namespace: "arc-runners" - arc-controller-namespace: "arc-systems" - wait-to-running: "true" - wait-to-finish: "false" - - - name: Upgrade the gha-runner-scale-set - shell: bash - run: | - helm upgrade --install "${{ steps.install_arc.outputs.ARC_NAME }}" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{ env.TARGET_REPO }}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.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" \ - ./charts/gha-runner-scale-set \ - --debug - - - name: Assert that the listener is deleted while jobs are running - shell: bash - run: | - count=0 - while true; do - LISTENER_COUNT="$(kubectl get pods -l actions.github.com/scale-set-name=${{ steps.install_arc.outputs.ARC_NAME }} -n arc-systems --field-selector=status.phase=Running -o=jsonpath='{.items}' | jq 'length')" - RUNNERS_COUNT="$(kubectl get pods -l app.kubernetes.io/component=runner -n arc-runners --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" - exit 0 - fi - if [ "$count" -ge 60 ]; then - echo "Timeout waiting for listener to be deleted" - echo "$RESOURCES" - exit 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 - - - name: Assert that the listener goes back up after the jobs are done - shell: bash - run: | - count=0 - while true; do - LISTENER_COUNT="$(kubectl get pods -l actions.github.com/scale-set-name=${{ steps.install_arc.outputs.ARC_NAME }} -n arc-systems --field-selector=status.phase=Running -o=jsonpath='{.items}' | jq 'length')" - RUNNERS_COUNT="$(kubectl get pods -l app.kubernetes.io/component=runner -n arc-runners --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" - exit 0 - fi - if [ "$count" -ge 120 ]; then - echo "Timeout waiting for listener to be recreated" - echo "$RESOURCES" - exit 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 - - - name: Gather logs and cleanup - shell: bash - if: always() - run: | - helm uninstall "${{ steps.install_arc.outputs.ARC_NAME }}" --namespace "arc-runners" --debug - 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: - runs-on: ubuntu-latest - timeout-minutes: 20 - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id - env: - WORKFLOW_FILE: arc-test-workflow.yaml - steps: - - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - - - uses: ./.github/actions/setup-arc-e2e - id: setup - with: - app-id: ${{secrets.E2E_TESTS_ACCESS_APP_ID}} - app-pk: ${{secrets.E2E_TESTS_ACCESS_PK}} - image-name: ${{env.IMAGE_NAME}} - image-tag: ${{env.IMAGE_VERSION}} - target-org: ${{env.TARGET_ORG}} - - - name: Install gha-runner-scale-set-controller - id: install_arc_controller - run: | - helm install arc \ - --namespace "arc-systems" \ - --create-namespace \ - --set image.repository=${{ env.IMAGE_NAME }} \ - --set image.tag=${{ env.IMAGE_VERSION }} \ - --set flags.updateStrategy="eventual" \ - ./charts/gha-runner-scale-set-controller \ - --debug - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -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" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l app.kubernetes.io/name=gha-rs-controller - kubectl get pod -n arc-systems - kubectl describe deployment arc-gha-rs-controller -n arc-systems - - - name: Install gha-runner-scale-set - id: install_arc - run: | - ARC_NAME=${{github.job}}-$(date +'%M%S')$((($RANDOM + 100) % 100 + 1)) - helm install "$ARC_NAME" \ - --namespace "arc-runners" \ - --create-namespace \ - --set githubConfigUrl="https://github.com/${{ env.TARGET_ORG }}/${{env.TARGET_REPO}}" \ - --set githubConfigSecret.github_token="${{ steps.setup.outputs.token }}" \ - --set minRunners=5 \ - ./charts/gha-runner-scale-set \ - --debug - echo "ARC_NAME=$ARC_NAME" >> $GITHUB_OUTPUT - count=0 - while true; do - POD_NAME=$(kubectl get pods -n arc-systems -l actions.github.com/scale-set-name=$ARC_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=$ARC_NAME" - exit 1 - fi - sleep 1 - count=$((count+1)) - done - kubectl wait --timeout=30s --for=condition=ready pod -n arc-systems -l actions.github.com/scale-set-name=$ARC_NAME - kubectl get pod -n arc-systems - - name: Ensure 5 runners are up - run: | - count=0 - while true; do - pod_count=$(kubectl get pods -n arc-runners --no-headers | wc -l) - if [[ "$pod_count" = 5 ]]; then - echo "5 pods are up!" - break - fi - if [[ "$count" -ge 12 ]]; then - echo "Timeout waiting for 5 pods to be created" - exit 1 - fi - sleep 1 - count=$((count+1)) - done diff --git a/README.md b/README.md index 8a3711be..1dd7a512 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ [![awesome-runners](https://img.shields.io/badge/listed%20on-awesome--runners-blue.svg)](https://github.com/jonico/awesome-runners) [![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/actions-runner-controller)](https://artifacthub.io/packages/search?repo=actions-runner-controller) +> [!NOTE] +> This has been forked from upstream in order to customize the metrics-server behaviour for our internal use case. + ## About Actions Runner Controller (ARC) is a Kubernetes operator that orchestrates and scales self-hosted runners for GitHub Actions. diff --git a/pkg/actionsmetrics/event_reader.go b/pkg/actionsmetrics/event_reader.go index 606891fe..2df46d8d 100644 --- a/pkg/actionsmetrics/event_reader.go +++ b/pkg/actionsmetrics/event_reader.go @@ -64,6 +64,10 @@ func (reader *EventReader) ProcessWorkflowJobEvent(ctx context.Context, event in keysAndValues = []interface{}{"job_id", fmt.Sprint(*e.WorkflowJob.ID)} ) + if len(e.WorkflowJob.Labels) == 0 { + return + } + runsOn := strings.Join(e.WorkflowJob.Labels, `,`) labels["runs_on"] = runsOn @@ -75,10 +79,6 @@ func (reader *EventReader) ProcessWorkflowJobEvent(ctx context.Context, event in labels["repository"] = *n keysAndValues = append(keysAndValues, "repository", *n) } - if n := e.Repo.FullName; n != nil { - labels["repository_full_name"] = *n - keysAndValues = append(keysAndValues, "repository_full_name", *n) - } if e.Repo.Owner != nil { if l := e.Repo.Owner.Login; l != nil { @@ -98,24 +98,26 @@ func (reader *EventReader) ProcessWorkflowJobEvent(ctx context.Context, event in labels["organization"] = org var wn string - var hb string if e.WorkflowJob != nil { if n := e.WorkflowJob.WorkflowName; n != nil { wn = *n keysAndValues = append(keysAndValues, "workflow_name", *n) } - if n := e.WorkflowJob.HeadBranch; n != nil { - hb = *n - keysAndValues = append(keysAndValues, "head_branch", *n) - } } labels["workflow_name"] = wn - labels["head_branch"] = hb + + is_main_branch := "false" + + if e.WorkflowJob.HeadBranch != nil && (strings.EqualFold(*e.WorkflowJob.HeadBranch, "main") || strings.EqualFold(*e.WorkflowJob.HeadBranch, "master")) { + is_main_branch = "true" + } + + labels["is_main_branch"] = is_main_branch log := reader.Log.WithValues(keysAndValues...) // switch on job status - switch action := e.GetAction(); action { + switch action := *e.WorkflowJob.Status; strings.ToLower(action) { case "queued": githubWorkflowJobsQueuedTotal.With(labels).Inc() @@ -131,13 +133,17 @@ func (reader *EventReader) ProcessWorkflowJobEvent(ctx context.Context, event in log.Error(err, "reading workflow job log") return } else { - log.Info("reading workflow_job logs") + log.Info("reading workflow_job logs for in progress job", "workflow_job_status", *e.WorkflowJob.Status, "parseResult", parseResult) } githubWorkflowJobQueueDurationSeconds.With(labels).Observe(parseResult.QueueTime.Seconds()) case "completed": - githubWorkflowJobsCompletedTotal.With(labels).Inc() + var rn string + if n := e.WorkflowJob.RunnerName; n != nil { + rn = *n + } + githubWorkflowJobsCompletedTotal.With(extraLabel("runner_name", rn, labels)).Inc() // job_conclusion -> (neutral, success, skipped, cancelled, timed_out, action_required, failure) githubWorkflowJobConclusionsTotal.With(extraLabel("job_conclusion", *e.WorkflowJob.Conclusion, labels)).Inc() @@ -162,7 +168,7 @@ func (reader *EventReader) ProcessWorkflowJobEvent(ctx context.Context, event in s := parseResult.RunTime.Seconds() runTimeSeconds = &s - log.WithValues(keysAndValues...).Info("reading workflow_job logs", "exit_code", exitCode) + log.Info("reading workflow_job logs for completed job", "exit_code", exitCode, "run_time_seconds", *runTimeSeconds, "parseResult", parseResult) } if *e.WorkflowJob.Conclusion == "failure" { @@ -199,8 +205,10 @@ func (reader *EventReader) ProcessWorkflowJobEvent(ctx context.Context, event in ).Inc() } - if runTimeSeconds != nil { - githubWorkflowJobRunDurationSeconds.With(extraLabel("job_conclusion", *e.WorkflowJob.Conclusion, labels)).Observe(*runTimeSeconds) + if *e.WorkflowJob.Conclusion != "cancelled" && *e.WorkflowJob.Conclusion != "skipped" && *e.WorkflowJob.Conclusion != "timed_out" { + if runTimeSeconds != nil { + githubWorkflowJobRunDurationSeconds.With(extraLabel("job_conclusion", *e.WorkflowJob.Conclusion, labels)).Observe(*runTimeSeconds) + } } } } @@ -232,6 +240,15 @@ func (reader *EventReader) fetchAndParseWorkflowJobLogs(ctx context.Context, e * if err != nil { return nil, err } + if *e.WorkflowJob.Status == "in_progress" { + if strings.Contains(url.String(), "actions-results") { + return &ParseResult{ + ExitCode: "", + QueueTime: time.Duration(0), + RunTime: time.Duration(0), + }, nil + } + } jobLogs, err := http.DefaultClient.Get(url.String()) if err != nil { return nil, err @@ -252,7 +269,8 @@ func (reader *EventReader) fetchAndParseWorkflowJobLogs(ctx context.Context, e * lines := bufio.NewScanner(jobLogs.Body) for lines.Scan() { - matches := logLine.FindStringSubmatch(lines.Text()) + ln := strings.ReplaceAll(lines.Text(), "\uFEFF", "") + matches := logLine.FindStringSubmatch(ln) if matches == nil { continue } @@ -273,7 +291,7 @@ func (reader *EventReader) fetchAndParseWorkflowJobLogs(ctx context.Context, e * continue } - if strings.HasPrefix(line, "Job is about to start running on the runner:") { + if strings.HasPrefix(strings.ToLower(line), strings.ToLower("Job is about to start running on the runner:")) || strings.HasPrefix(strings.ToLower(line), strings.ToLower("Current runner version:")) { startedTime, _ = time.Parse(time.RFC3339, timestamp) continue } diff --git a/pkg/actionsmetrics/metrics.go b/pkg/actionsmetrics/metrics.go index 6a5a0123..bb13e879 100644 --- a/pkg/actionsmetrics/metrics.go +++ b/pkg/actionsmetrics/metrics.go @@ -5,11 +5,44 @@ package actionsmetrics import ( + "fmt" + "os" + "strconv" + "strings" + "github.com/prometheus/client_golang/prometheus" "sigs.k8s.io/controller-runtime/pkg/metrics" ) +const ( + prometheusRunBucketIntervalsName = "PROMETHEUS_RUN_BUCKET_INTERVALS" + prometheusQueueBucketIntervalsName = "PROMETHEUS_QUEUE_BUCKET_INTERVALS" +) + func init() { + queueBuckets := defaultRuntimeBuckets + if _, ok := os.LookupEnv(prometheusQueueBucketIntervalsName); ok { + buckets, err := parseBucketsString(os.Getenv(prometheusQueueBucketIntervalsName)) + if err != nil { + fmt.Fprintf(os.Stderr, "Warning: Failed to parse %s, using default buckets: %s\n", prometheusQueueBucketIntervalsName, err) + } else { + queueBuckets = buckets + } + } + + runBuckets := defaultRuntimeBuckets + if _, ok := os.LookupEnv(prometheusRunBucketIntervalsName); ok { + buckets, err := parseBucketsString(os.Getenv(prometheusRunBucketIntervalsName)) + if err != nil { + fmt.Fprintf(os.Stderr, "Warning: Failed to parse %s, using default buckets: %s\n", prometheusRunBucketIntervalsName, err) + } else { + runBuckets = buckets + } + } + + githubWorkflowJobQueueDurationSeconds = initGithubWorkflowJobQueueDurationSeconds(queueBuckets) + githubWorkflowJobRunDurationSeconds = initGithubWorkflowJobRunDurationSeconds(runBuckets) + metrics.Registry.MustRegister( githubWorkflowJobQueueDurationSeconds, githubWorkflowJobRunDurationSeconds, @@ -21,77 +54,102 @@ func init() { ) } -var runtimeBuckets []float64 = []float64{ - 0.01, - 0.05, - 0.1, - 0.5, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 12, - 15, - 18, - 20, - 25, - 30, - 40, - 50, - 60, - 70, - 80, - 90, - 100, - 110, - 120, - 150, - 180, - 210, - 240, - 300, - 360, - 420, - 480, - 540, - 600, - 900, - 1200, - 1800, - 2400, - 3000, - 3600, -} +var ( + defaultRuntimeBuckets = []float64{ + 0.01, + 0.05, + 0.1, + 0.5, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 12, + 15, + 18, + 20, + 25, + 30, + 40, + 50, + 60, + 70, + 80, + 90, + 100, + 110, + 120, + 150, + 180, + 210, + 240, + 300, + 360, + 420, + 480, + 540, + 600, + 900, + 1200, + 1800, + 2400, + 3000, + 3600, + } +) func metricLabels(extras ...string) []string { return append(append([]string{}, commonLabels...), extras...) } -var ( - commonLabels = []string{"runs_on", "job_name", "organization", "repository", "repository_full_name", "owner", "workflow_name", "head_branch"} - githubWorkflowJobQueueDurationSeconds = prometheus.NewHistogramVec( +func parseBucketsString(value string) ([]float64, error) { + valuesStr := strings.Split(value, ",") + buckets := make([]float64, 0, len(valuesStr)) + + for _, str := range valuesStr { + val, err := strconv.ParseFloat(str, 64) + if err != nil { + return nil, err + } + buckets = append(buckets, val) + } + + return buckets, nil +} + +func initGithubWorkflowJobQueueDurationSeconds(buckets []float64) *prometheus.HistogramVec { + return prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "github_workflow_job_queue_duration_seconds", Help: "Queue times for workflow jobs in seconds", - Buckets: runtimeBuckets, + Buckets: buckets, }, metricLabels(), ) - githubWorkflowJobRunDurationSeconds = prometheus.NewHistogramVec( +} + +func initGithubWorkflowJobRunDurationSeconds(buckets []float64) *prometheus.HistogramVec { + return prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "github_workflow_job_run_duration_seconds", Help: "Run times for workflow jobs in seconds", - Buckets: runtimeBuckets, + Buckets: buckets, }, metricLabels("job_conclusion"), ) - githubWorkflowJobConclusionsTotal = prometheus.NewCounterVec( +} + +var ( + commonLabels = []string{"runs_on", "job_name", "organization", "repository", "owner", "workflow_name", "is_main_branch"} + githubWorkflowJobQueueDurationSeconds *prometheus.HistogramVec + githubWorkflowJobRunDurationSeconds *prometheus.HistogramVec + githubWorkflowJobConclusionsTotal = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "github_workflow_job_conclusions_total", Help: "Conclusions for tracked workflow jobs", @@ -117,7 +175,7 @@ var ( Name: "github_workflow_jobs_completed_total", Help: "Total count of workflow jobs completed (events where job_status=completed)", }, - metricLabels(), + metricLabels("runner_name"), ) githubWorkflowJobFailuresTotal = prometheus.NewCounterVec( prometheus.CounterOpts{