diff --git a/.forgejo/cascading-pr-setup-forgejo b/.forgejo/cascading-pr-setup-forgejo deleted file mode 100755 index 06472a7..0000000 --- a/.forgejo/cascading-pr-setup-forgejo +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -ex - -setup_forgejo=$1 -setup_forgejo_pr=$2 -runner=$3 -runner_pr=$4 - -url=$(jq --raw-output .head.repo.html_url < $runner_pr) -test "$url" != null -branch=$(jq --raw-output .head.ref < $runner_pr) -test "$branch" != null -cd $setup_forgejo -./utils/upgrade-runner.sh $url @$branch -date > last-upgrade diff --git a/.forgejo/labelscompare.py b/.forgejo/labelscompare.py deleted file mode 100644 index 2274d38..0000000 --- a/.forgejo/labelscompare.py +++ /dev/null @@ -1,24 +0,0 @@ -import json - -expectedLabels = { - "maintainer": "contact@forgejo.org", - "org.opencontainers.image.authors": "Forgejo", - "org.opencontainers.image.url": "https://forgejo.org", - "org.opencontainers.image.documentation": "https://forgejo.org/docs/latest/admin/actions/#forgejo-runner", - "org.opencontainers.image.source": "https://code.forgejo.org/forgejo/runner", - "org.opencontainers.image.version": "1.2.3", - "org.opencontainers.image.vendor": "Forgejo", - "org.opencontainers.image.licenses": "MIT", - "org.opencontainers.image.title": "Forgejo Runner", - "org.opencontainers.image.description": "A runner for Forgejo Actions.", -} -inspect = None -with open("./labels.json", "r") as f: - inspect = json.load(f) - -assert inspect -labels = inspect[0]["Config"]["Labels"] - -for k, v in expectedLabels.items(): - assert k in labels, f"'{k}' is missing from labels" - assert labels[k] == v, f"expected {v} in key {k}, found {labels[k]}" diff --git a/.forgejo/testdata/ipv6.yml b/.forgejo/testdata/ipv6.yml deleted file mode 100644 index e0f7588..0000000 --- a/.forgejo/testdata/ipv6.yml +++ /dev/null @@ -1,11 +0,0 @@ ---- -on: push -jobs: - ipv6: - runs-on: docker - container: - image: code.forgejo.org/oci/debian:bookworm - steps: - - run: | - apt update -qq ; apt --quiet install -qq --yes iputils-ping - ping -c 1 -6 ::1 diff --git a/.forgejo/workflows/build-release-integration.yml b/.forgejo/workflows/build-release-integration.yml index 7f92218..94c74f8 100644 --- a/.forgejo/workflows/build-release-integration.yml +++ b/.forgejo/workflows/build-release-integration.yml @@ -1,18 +1,12 @@ name: Integration tests for the release process -on: +on: push: paths: - go.mod - Dockerfile - .forgejo/workflows/build-release.yml - .forgejo/workflows/build-release-integration.yml - pull_request: - paths: - - go.mod - - Dockerfile - - .forgejo/workflows/build-release.yml - - .forgejo/workflows/build-release-integration.yml jobs: release-simulation: @@ -26,7 +20,7 @@ jobs: with: user: root password: admin1234 - image-version: 1.20 + image-version: 1.19 lxc-ip-prefix: 10.0.9 - name: publish @@ -52,13 +46,13 @@ jobs: # rsync -a --exclude .git ./ $dir/ rm $(find $dir/.forgejo/workflows/*.yml | grep -v build-release.yml) - forgejo-test-helper.sh push $dir $url root runner - sha=$(forgejo-test-helper.sh branch_tip $url root/runner main) + forgejo-test-helper.sh push $dir $url root runner |& tee $dir/pushed + eval $(grep '^sha=' < $dir/pushed) # # Push a tag to trigger the release workflow and wait for it to complete # - forgejo-curl.sh api_json --data-raw '{"tag_name": "v'$version'", "target": "'$sha'"}' $url/api/v1/repos/root/runner/tags + forgejo-test-helper.sh api POST $url repos/root/runner/tags ${{ steps.forgejo.outputs.token }} --data-raw '{"tag_name": "v'$version'", "target": "'$sha'"}' LOOPS=180 forgejo-test-helper.sh wait_success "$url" root/runner $sha # @@ -85,6 +79,3 @@ jobs: done docker pull ${{ steps.forgejo.outputs.host-port }}/root/runner:$version - - docker inspect ${{ steps.forgejo.outputs.host-port}}/root/runner:$version > labels.json - python3 .forgejo/labelscompare.py diff --git a/.forgejo/workflows/build-release.yml b/.forgejo/workflows/build-release.yml index 162befb..c09049f 100644 --- a/.forgejo/workflows/build-release.yml +++ b/.forgejo/workflows/build-release.yml @@ -5,8 +5,8 @@ # Build the runner binaries and OCI images # # ROLE: forgejo-integration -# DOER: forgejo-ci -# TOKEN: +# DOER: release-team +# TOKEN: # name: Build release @@ -35,7 +35,8 @@ jobs: - name: Sanitize the name of the repository id: repository run: | - echo "value=${GITHUB_REPOSITORY##*/}" >> "$GITHUB_OUTPUT" + repository="${{ github.repository }}" + echo "value=${repository##*/}" >> "$GITHUB_OUTPUT" - name: create test TOKEN id: token @@ -54,7 +55,8 @@ jobs: - name: version from ref_name id: tag-version run: | - version=${GITHUB_REF_NAME##*v} + version="${{ github.ref_name }}" + version=${version##*v} echo "value=$version" >> "$GITHUB_OUTPUT" - name: release notes @@ -70,14 +72,13 @@ jobs: - name: build without TOKEN if: ${{ secrets.TOKEN == '' }} - uses: https://code.forgejo.org/forgejo/forgejo-build-publish/build@v5 + uses: https://code.forgejo.org/forgejo/forgejo-build-publish/build@v1 with: forgejo: "${{ env.GITHUB_SERVER_URL }}" owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" repository: "${{ steps.repository.outputs.value }}" doer: root - sha: "${{ github.sha }}" - release-version: "${{ steps.tag-version.outputs.value }}" + tag-version: "${{ steps.tag-version.outputs.value }}" token: ${{ steps.token.outputs.value }} platforms: linux/amd64,linux/arm64 release-notes: "${{ steps.release-notes.outputs.value }}" @@ -87,14 +88,13 @@ jobs: - name: build with TOKEN if: ${{ secrets.TOKEN != '' }} - uses: https://code.forgejo.org/forgejo/forgejo-build-publish/build@v5 + uses: https://code.forgejo.org/forgejo/forgejo-build-publish/build@v1 with: forgejo: "${{ env.GITHUB_SERVER_URL }}" owner: "${{ env.GITHUB_REPOSITORY_OWNER }}" repository: "${{ steps.repository.outputs.value }}" doer: "${{ secrets.DOER }}" - sha: "${{ github.sha }}" - release-version: "${{ steps.tag-version.outputs.value }}" + tag-version: "${{ steps.tag-version.outputs.value }}" token: "${{ secrets.TOKEN }}" platforms: linux/amd64,linux/arm64 release-notes: "${{ steps.release-notes.outputs.value }}" diff --git a/.forgejo/workflows/cascade-setup-forgejo.yml b/.forgejo/workflows/cascade-setup-forgejo.yml deleted file mode 100644 index 6d94f01..0000000 --- a/.forgejo/workflows/cascade-setup-forgejo.yml +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-License-Identifier: MIT -on: - pull_request_target: - types: - - opened - - synchronize - - closed -jobs: - cascade: - runs-on: docker - if: vars.CASCADE != 'no' - steps: - - uses: actions/cascading-pr@v1 - with: - origin-url: ${{ env.GITHUB_SERVER_URL }} - origin-repo: forgejo/runner - origin-token: ${{ secrets.CASCADING_PR_ORIGIN }} - origin-pr: ${{ github.event.pull_request.number }} - destination-url: ${{ env.GITHUB_SERVER_URL }} - destination-repo: actions/setup-forgejo - destination-fork-repo: cascading-pr/setup-forgejo - destination-branch: main - destination-token: ${{ secrets.CASCADING_PR_DESTINATION }} - close-merge: true - update: .forgejo/cascading-pr-setup-forgejo diff --git a/.forgejo/workflows/example-docker-compose.yml b/.forgejo/workflows/example-docker-compose.yml deleted file mode 100644 index 4e2f547..0000000 --- a/.forgejo/workflows/example-docker-compose.yml +++ /dev/null @@ -1,70 +0,0 @@ -# SPDX-License-Identifier: MIT -on: - push: - branches: - - 'main' - pull_request: - -jobs: - example-docker-compose: - runs-on: self-hosted - steps: - - uses: actions/checkout@v4 - - - name: Install docker - run: | - apt-get update -qq - export DEBIAN_FRONTEND=noninteractive - apt-get install -qq -y ca-certificates curl gnupg - install -m 0755 -d /etc/apt/keyrings - curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg - echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - apt-get update -qq - apt-get install -qq -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin=2.20.2-1~debian.11~bullseye - docker version - # - # docker compose is prone to non backward compatible changes, pin it - # - apt-get install -qq -y docker-compose-plugin=2.20.2-1~debian.11~bullseye - docker compose version - - - name: run the example - run: | - set -x - cd examples/docker-compose - secret=$(openssl rand -hex 20) - sed -i -e "s/{SHARED_SECRET}/$secret/" compose-forgejo-and-runner.yml - cli="docker compose --progress quiet -f compose-forgejo-and-runner.yml" - # - # Launch Forgejo & the runner - # - $cli up -d - for delay in $(seq 60) ; do test -f /srv/runner-data/.runner && break ; sleep 30 ; done - test -f /srv/runner-data/.runner - # - # Run the demo workflow - # - cli="$cli -f compose-demo-workflow.yml" - $cli up -d demo-workflow - # - # Wait for the demo workflow to complete - # - success='DEMO WORKFLOW SUCCESS' - failure='DEMO WORKFLOW FAILURE' - for delay in $(seq 60) ; do - $cli logs demo-workflow > /tmp/out - grep --quiet "$success" /tmp/out && break - grep --quiet "$failure" /tmp/out && break - $cli ps --all - $cli logs --tail=20 runner-daemon demo-workflow - sleep 30 - done - grep --quiet "$success" /tmp/out - $cli logs runner-daemon > /tmp/runner.log - grep --quiet 'Start image=code.forgejo.org/oci/node:20-bookworm' /tmp/runner.log - - - name: full docker compose logs - if: always() - run: | - cd examples/docker-compose - docker compose -f compose-forgejo-and-runner.yml -f compose-demo-workflow.yml logs diff --git a/.forgejo/workflows/publish-release.yml b/.forgejo/workflows/publish-release.yml index 35d8662..6b455a9 100644 --- a/.forgejo/workflows/publish-release.yml +++ b/.forgejo/workflows/publish-release.yml @@ -13,7 +13,7 @@ # GPG_PRIVATE_KEY: # GPG_PASSPHRASE: # -name: publish +name: pubish on: push: @@ -24,6 +24,13 @@ jobs: runs-on: self-hosted if: secrets.DOER != '' && secrets.FORGEJO != '' && secrets.TO_OWNER != '' && secrets.FROM_OWNER != '' && secrets.TOKEN != '' steps: + - name: install the certificate authority + if: secrets.ROLE == 'forgejo-release' + run: | + apt-get install -qq -y wget + wget --no-check-certificate -O /usr/local/share/ca-certificates/enough.crt https://forgejo.octopuce.forgejo.org/forgejo/enough/raw/branch/main/certs/2023-05-13/ca.crt + update-ca-certificates --fresh + - uses: actions/checkout@v3 - name: copy & sign @@ -34,7 +41,6 @@ jobs: to-owner: ${{ secrets.TO_OWNER }} repo: "runner" ref-name: ${{ github.ref_name }} - container-suffixes: " " doer: ${{ secrets.DOER }} token: ${{ secrets.TOKEN }} gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }} diff --git a/.forgejo/workflows/test.yml b/.forgejo/workflows/test.yml index 677ab68..aee2927 100644 --- a/.forgejo/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -1,9 +1,7 @@ name: checks -on: - push: - branches: - - 'main' - pull_request: +on: + - pull_request + - push env: FORGEJO_HOST_PORT: 'forgejo:3000' @@ -15,14 +13,14 @@ env: GOPROXY: https://goproxy.io,direct jobs: - build-and-tests: - name: build and test + tests: + name: check and test if: github.repository_owner != 'forgejo-integration' && github.repository_owner != 'forgejo-experimental' && github.repository_owner != 'forgejo-release' runs-on: docker services: forgejo: - image: codeberg.org/forgejo/forgejo:1.21 + image: codeberg.org/forgejo-integration/forgejo:1.20.0-4-rc2 env: FORGEJO__security__INSTALL_LOCK: "true" FORGEJO__log__LEVEL: "debug" @@ -40,69 +38,17 @@ jobs: with: go-version: '1.21' - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 - run: make vet - run: make build - - uses: https://code.forgejo.org/actions/upload-artifact@v3 - with: - name: forgejo-runner - path: forgejo-runner - - name: check the forgejo server is responding run: | + set -x apt-get update -qq apt-get install -y -qq jq curl test $FORGEJO_ADMIN_USER = $(curl -sS http://$FORGEJO_ADMIN_USER:$FORGEJO_ADMIN_PASSWORD@$FORGEJO_HOST_PORT/api/v1/user | jq --raw-output .login) - run: make FORGEJO_URL=http://$FORGEJO_HOST_PORT test - - runner-exec-tests: - needs: [build-and-tests] - name: runner exec tests - if: github.repository_owner != 'forgejo-integration' && github.repository_owner != 'forgejo-experimental' && github.repository_owner != 'forgejo-release' - runs-on: self-hosted - - steps: - - - uses: actions/checkout@v4 - - - uses: https://code.forgejo.org/actions/download-artifact@v3 - with: - name: forgejo-runner - - - name: install docker - run: | - mkdir /etc/docker - cat > /etc/docker/daemon.json <& /tmp/out ; then - cat /tmp/out - echo "IPv6 not enabled, should fail" - exit 1 - fi diff --git a/Dockerfile b/Dockerfile index 50f1965..ce36d7a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ -FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/tonistiigi/xx AS xx +FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx -FROM --platform=$BUILDPLATFORM code.forgejo.org/oci/golang:1.21-alpine3.19 as build-env +FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.21-alpine3.18 as build-env # # Transparently cross compile for the target platform @@ -19,23 +19,13 @@ WORKDIR /srv RUN make clean && make build -FROM code.forgejo.org/oci/alpine:3.19 -ARG RELEASE_VERSION +FROM docker.io/library/alpine:3.18 +LABEL maintainer="contact@forgejo.org" + RUN apk add --no-cache git bash COPY --from=build-env /srv/forgejo-runner /bin/forgejo-runner -LABEL maintainer="contact@forgejo.org" \ - org.opencontainers.image.authors="Forgejo" \ - org.opencontainers.image.url="https://forgejo.org" \ - org.opencontainers.image.documentation="https://forgejo.org/docs/latest/admin/actions/#forgejo-runner" \ - org.opencontainers.image.source="https://code.forgejo.org/forgejo/runner" \ - org.opencontainers.image.version="${RELEASE_VERSION}" \ - org.opencontainers.image.vendor="Forgejo" \ - org.opencontainers.image.licenses="MIT" \ - org.opencontainers.image.title="Forgejo Runner" \ - org.opencontainers.image.description="A runner for Forgejo Actions." - ENV HOME=/data USER 1000:1000 diff --git a/Makefile b/Makefile index 3413168..40a5b44 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GO ?= go SHASUM ?= shasum -a 256 HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" ) XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest -XGO_VERSION := go-1.21.x +XGO_VERSION := go-1.18.x GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10 LINUX_ARCHS ?= linux/amd64,linux/arm64 diff --git a/README.md b/README.md index ccf2e8b..3316398 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,52 @@ **WARNING:** this is [alpha release quality](https://en.wikipedia.org/wiki/Software_release_life_cycle#Alpha) code and should not be considered secure enough to deploy in production. -A daemon that connects to a Forgejo instance and runs jobs for continous integration. The [installation and usage instructions](https://forgejo.org/docs/next/admin/actions/) are part of the Forgejo documentation. +A daemon that connects to a Forgejo instance and runs jobs for continous integration. The high level [installation instructions](https://forgejo.org/docs/next/admin/actions/) are part of the Forgejo documentation. -# Reporting bugs +# Configuration -When filing a bug in [the issue tracker](https://code.forgejo.org/forgejo/runner/issues), it is very helpful to propose a pull request [in the end-to-end tests](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions) repository that adds a reproducer. It will fail the CI and unambiguously demonstrate that the problem exists. In most cases it is enough to add a workflow ([see the echo example](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-echo)). For more complicated cases it is also possible to add a runner config file as well as shell scripts to setup and teardown the test case ([see the service example](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-service)). +Display the usage with `forgejo-runner --help`. + +For more information on the configuration file, see the [commented example](internal/pkg/config/config.example.yaml). # Hacking -The Forgejo runner depends on [a fork of ACT](https://code.forgejo.org/forgejo/act) and is a dependency of the [setup-forgejo action](https://code.forgejo.org/actions/setup-forgejo). See [the full dependency graph](https://code.forgejo.org/actions/cascading-pr/#forgejo-dependencies) for a global view. +The Forgejo runner depends on [a fork of ACT](https://code.forgejo.org/forgejo/act) and is a dependency of the [setup-forgejo action](https://code.forgejo.org/actions/setup-forgejo). Together they provide a development environment with end to end testing. Each repository also has some unit testing that can be used to quickly detect the simplest mistakes such as a failure to compile or static code checking failures (vulnerability, lint, etc.). + +Assuming the modifications to the [Forgejo runner](https://code.forgejo.org/forgejo/runner) are pushed to a fork in a branch named `wip-runner-change`, a pull request will verify it compiles and the binary is sane (running `forgejo-runner --version`). It will not verify that it is able to properly run jobs when connected to a live Forgejo instance. + +For end to end testing, a branch should be pushed to a fork of the [setup-forgejo action](https://code.forgejo.org/actions/setup-forgejo) with a [modification to the tests](https://code.forgejo.org/actions/setup-forgejo/src/commit/ae7f03683b7b05c7d9c6aaeacaf27843de0366a4/.forgejo/workflows/integration.yml#L10-L19), similar to: + +```yaml +# +# Uncomment the following for a shortcut to debugging the Forgejo runner. +# It will build the runner from a designated repository and branch instead of +# downloading it from a canonical release. +# +./forgejo-test-helper.sh build_runner https://code.forgejo.org/earl-warren/runner wip-runner-change +``` + +Where https://code.forgejo.org/earl-warren/runner is the URL of the Forgejo runner fork and `wip-runner-change` is the branch where the changes under test were pushed. When they do the `wip-runner-change` branch can be discarded. + +The runner can be released by merging the `wip-runner-change` branch and by pushing a new tag, for instance `v10.2.3`. For more information see the [documentation that details this release process](https://forgejo.org/docs/next/developer/RELEASE/#forgejo-runner-publication) in the Forgejo infrastructure. Once published, the [setup-forgejo](https://code.forgejo.org/actions/setup-forgejo/) action can be updated to default to this latest version knowing it already passed integration tests. + +## ACT + +Assuming the modifications to [ACT](https://code.forgejo.org/forgejo/act) are pushed to a fork in a branch named `wip-act-change`, a pull request will verify it compiles. It will not verify that the Forgejo runner can compile with it. + +For verifying it is compatible with the Forgejo runner, a branch should be pushed to a fork of the [Forgejo runner](https://code.forgejo.org/forgejo/runner) (for instance `wip-runner-change`) that uses the ACT version under test in `wip-act-change` by modifying `go.mod` to contain something like the following and running `go mod tidy`: + +``` +replace github.com/nektos/act => code.forgejo.org/earl-warren/act wip-act-change +``` + +Where https://code.forgejo.org/earl-warren/act is the URL of the ACT fork and `wip-act-change` is the branch where the changes under test were pushed. It will not verify that it is able to properly run jobs when connected to a live Forgejo instance. The `wip-runner-change` branch must, in turn, be tested as explained above. When the Forgejo runner modified to include the changes in the `wip-act-change` branch pass the end to end test of the `setup-forgejo` action, it is ready to be released. + +ACT can be released by merging the `wip-act-change` branch and by pushing a new tag, for instance `v48.8.20`. Once published, the Forgejo runner can be updated to default to this latest version knowing it already passed end to end tests with something like: + +``` +replace github.com/nektos/act => code.forgejo.org/forgejo/act v48.8.20 +``` ## Local debug @@ -53,9 +90,8 @@ cd runner ; rm -f forgejo-runner ; make forgejo-runner A Forgejo instance is launched with: ```shell -cd setup-forgejo -./forgejo.sh setup -firefox $(cat forgejo-url) +cd setup-forgejo ; ./forgejo.sh setup +firefox http://$(cat forgejo-ip):3000 ``` The user is `root` with password `admin1234`. The runner is registered with: @@ -63,7 +99,7 @@ The user is `root` with password `admin1234`. The runner is registered with: ``` cd setup-forgejo docker exec --user 1000 forgejo forgejo actions generate-runner-token > forgejo-runner-token -../runner/forgejo-runner register --no-interactive --instance "$(cat forgejo-url)" --name runner --token $(cat forgejo-runner-token) --labels docker:docker://node:20-bullseye,self-hosted:host://-self-hosted,lxc:lxc://debian:bullseye +../runner/forgejo-runner register --no-interactive --instance "http://$(cat forgejo-ip):3000/" --name runner --token $(cat forgejo-runner-token) --labels docker:docker://node:16-bullseye,self-hosted ``` And launched with: @@ -78,9 +114,7 @@ create a network that cannot reach the forgejo instance. ### Try a sample workflow -From the Forgejo web interface, create a repository and add the -following to `.forgejo/workflows/try.yaml`. It will launch the job and -the result can be observed from the `actions` tab. +From the Forgejo web interface, create a repository and add the following to `.forgejo/workflows/try.yaml`. It will launch the job and the result can be observed from the `actions` tab. ```yaml on: [push] diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index c4d9db3..89dafd2 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,102 +1,18 @@ # Release Notes -## 3.5.2 - -* Fix [crash in some cases when the YAML structure is not as expected](https://code.forgejo.org/forgejo/runner/issues/267). - -## 3.5.1 - -* Fix [CVE-2024-24557](https://nvd.nist.gov/vuln/detail/CVE-2024-24557) -* [Add report_interval option to config](https://code.forgejo.org/forgejo/runner/pulls/220) to allow setting the interval of status and log reports - -## 3.5.0 - -* [Allow graceful shutdowns](https://code.forgejo.org/forgejo/runner/pulls/202): when receiving a signal (INT or TERM) wait for running jobs to complete (up to shutdown_timeout). -* [Fix label declaration](https://code.forgejo.org/forgejo/runner/pulls/176): Runner in daemon mode now takes labels found in config.yml into account when declaration was successful. -* [Fix the docker compose example](https://code.forgejo.org/forgejo/runner/pulls/175) to workaround the race on labels. -* [Fix the kubernetes dind example](https://code.forgejo.org/forgejo/runner/pulls/169). -* [Rewrite ::group:: and ::endgroup:: commands like github](https://code.forgejo.org/forgejo/runner/pulls/183). -* [Added opencontainers labels to the image](https://code.forgejo.org/forgejo/runner/pulls/195) -* [Upgrade the default container to node:20](https://code.forgejo.org/forgejo/runner/pulls/203) - -## 3.4.1 - -* Fixes a regression introduced in 3.4.0 by which a job with no image explicitly set would - [be bound to the host](https://code.forgejo.org/forgejo/runner/issues/165) - network instead of a custom network (empty string in the configuration file). - -## 3.4.0 - -Although this version is able to run [actions/upload-artifact@v4](https://code.forgejo.org/actions/upload-artifact/src/tag/v4) and [actions/download-artifact@v4](https://code.forgejo.org/actions/download-artifact/src/tag/v4), these actions will fail because it does not run against GitHub.com. A fork of those two actions with this check disabled is made available at: - -* https://code.forgejo.org/forgejo/upload-artifact/src/tag/v4 -* https://code.forgejo.org/forgejo/download-artifact/src/tag/v4 - -and they can be used as shown in [an example from the end-to-end test suite](https://code.forgejo.org/forgejo/end-to-end/src/branch/main/actions/example-artifacts-v4/.forgejo/workflows/test.yml). - -* When running against codeberg.org, the default poll frequency is 30s instead of 2s. -* Fix compatibility issue with actions/{upload,download}-artifact@v4. -* Upgrade ACT v1.20.0 which brings: - * `[container].options` from the config file is exposed in containers created by the workflows - * the expressions in the value of `jobs..runs-on` are evaluated - * fix a bug causing the evaluated expression of `jobs..runs-on` to fail if it was an array - * mount `act-toolcache:/opt/hostedtoolcache` instead of `act-toolcache:/toolcache` - * a few improvements to the readability of the error messages displayed in the logs - * `amd64` can be used instead of `x86_64` and `arm64` intead of `aarch64` when specifying the architecture - * fixed YAML parsing bugs preventing dispatch workflows to be parsed correctly - * add support for `runs-on.labels` which is equivalent to `runs-on` followed by a list of labels - * the expressions in the service `ports` and `volumes` values are evaluated - * network aliases are only supported when the network is user specified, not when it is provided by the runner -* If `[runner].insecure` is true in the configuration, insecure cloning actions is allowed - -## 3.3.0 - -* Support IPv6 with addresses from a private range and NAT for - docker:// with --enable-ipv6 and [container].enable_ipv6 - lxc:// always - -## 3.2.0 - -* Support LXC container capabilities via `lxc:lxc://debian:bookworm:k8s` or `lxc:lxc://debian:bookworm:docker lxc k8s` -* Update ACT v1.16.0 to resolve a [race condition when bootstraping LXC templates](https://code.forgejo.org/forgejo/act/pulls/23) - -## 3.1.0 - -The `self-hosted` label that was hardwired to be a LXC container -running `debian:bullseye` was reworked and documented ([user guide](https://forgejo.org/docs/next/user/actions/#jobsjob_idruns-on) and [admin guide](https://forgejo.org/docs/next/admin/actions/#labels-and-runs-on)). - -There now are two different schemes: `lxc://` for LXC containers and -`host://` for running directly on the host. - -* Support the `host://` scheme for running directly on the host. -* Support the `lxc://` scheme in labels -* Update [code.forgejo.org/forgejo/act v1.14.0](https://code.forgejo.org/forgejo/act/pulls/19) to implement both self-hosted and LXC schemes - -## 3.0.3 - -* Update [code.forgejo.org/forgejo/act v1.13.0](https://code.forgejo.org/forgejo/runner/pulls/106) to keep up with github.com/nektos/act - -## 3.0.2 - -* Update [code.forgejo.org/forgejo/act v1.12.0](https://code.forgejo.org/forgejo/runner/pulls/106) to upgrade the node installed in the LXC container to node20 - -## 3.0.1 - -* Update [code.forgejo.org/forgejo/act v1.11.0](https://code.forgejo.org/forgejo/runner/pulls/86) to resolve a bug preventing actions based on node20 from running, such as [checkout@v4](https://code.forgejo.org/actions/checkout/src/tag/v4). - -## 3.0.0 +## v3.0.0 * Publish a rootless OCI image * Refactor the release process -## 2.5.0 +## v2.5.0 * Update [code.forgejo.org/forgejo/act v1.10.0](https://code.forgejo.org/forgejo/runner/pulls/71) -## 2.4.0 +## v2.4.0 * Update [code.forgejo.org/forgejo/act v1.9.0](https://code.forgejo.org/forgejo/runner/pulls/64) -## 2.3.0 +## v2.3.0 * Add support for [offline registration](https://forgejo.org/docs/next/admin/actions/#offline-registration). diff --git a/contrib/forgejo-runner.service b/contrib/forgejo-runner.service deleted file mode 100644 index ace922a..0000000 --- a/contrib/forgejo-runner.service +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Forgejo Runner -Documentation=https://forgejo.org/docs/latest/admin/actions/ -After=docker.service - -[Service] -ExecStart=forgejo-runner daemon -ExecReload=/bin/kill -s HUP $MAINPID - -# This user and working directory must already exist -User=runner -WorkingDirectory=/home/runner -Restart=on-failure -TimeoutSec=0 -RestartSec=10 - -[Install] -WantedBy=multi-user.target diff --git a/examples/README.md b/examples/README.md index f9dd774..d5a5b7e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,10 +1,12 @@ -This directory contains a collection of usage and deployment examples. +# Usage Examples for `act_runner` -Workflow examples can be found [in the documentation](https://forgejo.org/docs/next/user/actions/) -and in the [sources of the setup-forgejo](https://code.forgejo.org/actions/setup-forgejo/src/branch/main/testdata) action. +Welcome to our collection of usage and deployment examples specifically designed for Gitea setups. Whether you're a beginner or an experienced user, you'll find practical resources here that you can directly apply to enhance your Gitea experience. We encourage you to contribute your own insights and knowledge to make this collection even more comprehensive and valuable. | Section | Description | |-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [`docker`](docker) | using the host docker server by mounting the socket | -| [`docker-compose`](docker-compose) | all in one docker-compose with the Forgejo server, the runner and docker in docker | -| [`kubernetes`](kubernetes) | a sample deployment for the Forgejo runner | +| [`docker`](docker) | This section provides you with scripts and instructions tailored for running containers on a workstation or server where Docker is installed. It simplifies the process of setting up and managing your Gitea deployment using Docker. | +| [`docker-compose`](docker-compose) | In this section, you'll discover examples demonstrating how to utilize docker-compose to efficiently handle your Gitea deployments. It offers a straightforward approach to managing multiple containerized components of your Gitea setup. | +| [`kubernetes`](kubernetes) | If you're utilizing Kubernetes clusters for your infrastructure, this section is specifically designed for you. It presents examples and guidelines for configuring Gitea deployments within Kubernetes clusters, enabling you to leverage the scalability and flexibility of Kubernetes. | +| [`vm`](vm) | This section is dedicated to examples that assist you in setting up Gitea on virtual or physical servers. Whether you're working with virtual machines or physical hardware, you'll find helpful resources to guide you through the deployment process. | + +We hope these resources provide you with valuable insights and solutions for your Gitea setup. Feel free to explore, contribute, and adapt these examples to suit your specific requirements. diff --git a/examples/docker-compose/README.md b/examples/docker-compose/README.md index a3e6e9b..c3b714c 100644 --- a/examples/docker-compose/README.md +++ b/examples/docker-compose/README.md @@ -1,113 +1,20 @@ -## Docker compose with docker-in-docker +### Running `act_runner` using `docker-compose` -The `compose-forgejo-and-runner.yml` compose file runs a Forgejo -instance and registers a `Forgejo runner`. A docker server is also -launched within a container (using -[dind](https://hub.docker.com/_/docker/tags?name=dind)) and will be -used by the `Forgejo runner` to execute the workflows. - -### Quick start - -```sh -rm -fr /srv/runner-data /srv/forgejo-data -secret=$(openssl rand -hex 20) -sed -i -e "s/{SHARED_SECRET}/$secret/" compose-forgejo-and-runner.yml -docker compose -f compose-forgejo-and-runner.yml up -d -``` - -Visit http://0.0.0.0:8080/admin/actions/runners with login `root` and password `{ROOT_PASSWORD}` and see the runner is registered with the label `docker`. - -> NOTE: the `Your ROOT_URL in app.ini is "http://localhost:3000/", it's unlikely matching the site you are visiting.` message is a warning that can be ignored in the context of this example. - -```sh -docker compose -f compose-forgejo-and-runner.yml -f compose-demo-workflow.yml up demo-workflow -``` - -Visit http://0.0.0.0:8080/root/test/actions/runs/1 and see that the job ran. - - -### Running - -Create a shared secret with: - -```sh -openssl rand -hex 20 -``` - -Replace all occurences of {SHARED_SECRET} in -[compose-forgejo-and-runner.yml](compose-forgejo-and-runner.yml). - -> **NOTE:** a token obtained from the Forgejo web interface cannot be used as a shared secret. - -Replace {ROOT_PASSWORD} with a secure password in -[compose-forgejo-and-runner.yml](compose-forgejo-and-runner.yml). - -```sh -docker compose -f compose-forgejo-and-runner.yml up -Creating docker-compose_docker-in-docker_1 ... done -Creating docker-compose_forgejo_1 ... done -Creating docker-compose_runner-register_1 ... done -... -docker-in-docker_1 | time="2023-08-24T10:22:15.023338461Z" level=warning msg="WARNING: API is accessible on http://0.0.0.0:2376 -... -forgejo_1 | 2023/08/24 10:22:14 ...s/graceful/server.go:75:func1() [D] Starting server on tcp:0.0.0.0:3000 (PID: 19) -... -runner-daemon_1 | time="2023-08-24T10:22:16Z" level=info msg="Starting runner daemon" -``` - -### Manual testing - -To login the Forgejo instance: - -* URL: http://0.0.0.0:8080 -* user: `root` -* password: `{ROOT_PASSWORD}` - -`Forgejo Actions` is enabled by default when creating a repository. - -## Tests workflow - -The `compose-demo-workflow.yml` compose file runs two demo workflows: -* one to verify the `Forgejo runner` can pick up a task from the Forgejo instance -and run it to completion. -* one to verify docker can be run inside the `Forgejo runner` container. - -A new repository is created in root/test with the following workflows: - -#### `.forgejo/workflows/demo.yml`: - -```yaml -on: [push] -jobs: - test: - runs-on: docker - steps: - - run: echo All Good -``` - -#### `.forgejo/workflows/demo_docker.yml` - -```yaml -on: [push] -jobs: - test_docker: - runs-on: ubuntu-22.04 - steps: - - run: docker info -``` - -A wait loop expects the status of the check associated with the -commit in Forgejo to show "success" to assert the workflow was run. - -### Running - -```sh -$ docker-compose -f compose-forgejo-and-runner.yml -f compose-demo-workflow.yml up demo-workflow -... -demo-workflow_1 | To http://forgejo:3000/root/test -demo-workflow_1 | + 5ce134e...261cc79 main -> main (forced update) -demo-workflow_1 | branch 'main' set up to track 'http://root:admin1234@forgejo:3000/root/test/main'. -... -demo-workflow_1 | running +```yml ... + gitea: + image: gitea/gitea + ... + + runner: + image: gitea/act_runner + restart: always + depends_on: + - gitea + volumes: + - ./data/act_runner:/data + - /var/run/docker.sock:/var/run/docker.sock + environment: + - GITEA_INSTANCE_URL= + - GITEA_RUNNER_REGISTRATION_TOKEN= ``` diff --git a/examples/docker-compose/compose-demo-workflow.yml b/examples/docker-compose/compose-demo-workflow.yml deleted file mode 100644 index 90e7d52..0000000 --- a/examples/docker-compose/compose-demo-workflow.yml +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2024 The Forgejo Authors. -# SPDX-License-Identifier: MIT - -services: - - demo-workflow: - image: code.forgejo.org/oci/alpine:3.19 - links: - - forgejo - command: >- - sh -ec ' - apk add --quiet git curl jq ; - mkdir -p /srv/demo ; - cd /srv/demo ; - git init --initial-branch=main ; - mkdir -p .forgejo/workflows ; - echo "{ on: [push], jobs: { test: { runs-on: docker, steps: [ {uses: actions/checkout@v4}, { run: echo All Good } ] } } }" > .forgejo/workflows/demo.yml ; - echo "{ on: [push], jobs: { test_docker: { runs-on: ubuntu-22.04, steps: [ { run: docker info } ] } } }" > .forgejo/workflows/demo_docker.yml ; - git add . ; - git config user.email root@example.com ; - git config user.name username ; - git commit -m demo ; - while : ; do - git push --set-upstream --force http://root:{ROOT_PASSWORD}@forgejo:3000/root/test main && break ; - sleep 5 ; - done ; - sha=`git rev-parse HEAD` ; - for delay in 1 1 1 1 2 5 5 10 10 10 15 30 30 30 30 30 30 30 ; do - curl -sS -f http://forgejo:3000/api/v1/repos/root/test/commits/$$sha/status | jq --raw-output .state | tee status ; - if grep success status ; then echo DEMO WORKFLOW SUCCESS && break ; fi ; - if grep failure status ; then echo DEMO WORKFLOW FAILURE && break ; fi ; - sleep $$delay ; - done ; - grep success status || echo DEMO WORKFLOW FAILURE - ' diff --git a/examples/docker-compose/compose-forgejo-and-runner.yml b/examples/docker-compose/compose-forgejo-and-runner.yml deleted file mode 100644 index 4794985..0000000 --- a/examples/docker-compose/compose-forgejo-and-runner.yml +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2024 The Forgejo Authors. -# SPDX-License-Identifier: MIT - -# -# Create a secret with: -# -# openssl rand -hex 20 -# -# Replace all occurences of {SHARED_SECRET} below with the output. -# -# NOTE: a token obtained from the Forgejo web interface cannot be used -# as a shared secret. -# -# Replace {ROOT_PASSWORD} with a secure password -# - -volumes: - docker_certs: - -services: - - docker-in-docker: - image: code.forgejo.org/oci/docker:dind - hostname: docker # Must set hostname as TLS certificates are only valid for docker or localhost - privileged: true - environment: - DOCKER_TLS_CERTDIR: /certs - DOCKER_HOST: docker-in-docker - volumes: - - docker_certs:/certs - - forgejo: - image: codeberg.org/forgejo/forgejo:1.21 - command: >- - bash -c ' - /bin/s6-svscan /etc/s6 & - sleep 10 ; - su -c "forgejo forgejo-cli actions register --secret {SHARED_SECRET}" git ; - su -c "forgejo admin user create --admin --username root --password {ROOT_PASSWORD} --email root@example.com" git ; - sleep infinity - ' - environment: - FORGEJO__security__INSTALL_LOCK: "true" - FORGEJO__log__LEVEL: "debug" - FORGEJO__repository__ENABLE_PUSH_CREATE_USER: "true" - FORGEJO__repository__DEFAULT_PUSH_CREATE_PRIVATE: "false" - FORGEJO__repository__DEFAULT_REPO_UNITS: "repo.code,repo.actions" - volumes: - - /srv/forgejo-data:/data - ports: - - 8080:3000 - - runner-register: - image: code.forgejo.org/forgejo/runner:3.4.1 - links: - - docker-in-docker - - forgejo - environment: - DOCKER_HOST: tcp://docker-in-docker:2376 - volumes: - - /srv/runner-data:/data - user: 0:0 - command: >- - bash -ec ' - while : ; do - forgejo-runner create-runner-file --connect --instance http://forgejo:3000 --name runner --secret {SHARED_SECRET} && break ; - sleep 1 ; - done ; - sed -i -e "s|\"labels\": null|\"labels\": [\"docker:docker://code.forgejo.org/oci/node:20-bookworm\", \"ubuntu-22.04:docker://catthehacker/ubuntu:act-22.04\"]|" .runner ; - forgejo-runner generate-config > config.yml ; - sed -i -e "s|network: .*|network: host|" config.yml ; - sed -i -e "s|^ envs:$$| envs:\n DOCKER_HOST: tcp://docker:2376\n DOCKER_TLS_VERIFY: 1\n DOCKER_CERT_PATH: /certs/client|" config.yml ; - sed -i -e "s|^ options:| options: -v /certs/client:/certs/client|" config.yml ; - sed -i -e "s| valid_volumes: \[\]$$| valid_volumes:\n - /certs/client|" config.yml ; - chown -R 1000:1000 /data - ' - - runner-daemon: - image: code.forgejo.org/forgejo/runner:3.4.1 - links: - - docker-in-docker - - forgejo - environment: - DOCKER_HOST: tcp://docker:2376 - DOCKER_CERT_PATH: /certs/client - DOCKER_TLS_VERIFY: "1" - volumes: - - /srv/runner-data:/data - - docker_certs:/certs - command: >- - bash -c ' - while : ; do test -w .runner && forgejo-runner --config config.yml daemon ; sleep 1 ; done - ' diff --git a/examples/docker/README.md b/examples/docker/README.md index 628c99c..dde2d63 100644 --- a/examples/docker/README.md +++ b/examples/docker/README.md @@ -1,12 +1,8 @@ -The following assumes: - -* a docker server runs on the host -* the docker group of the host is GID 133 -* a `.runner` file exists in /tmp/data -* a `runner-config.yml` file exists in /tmp/data +### Run `act_runner` in a Docker Container ```sh -docker run -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/data:/data --user 1000:133 --rm code.forgejo.org/forgejo/runner:3.0.0 forgejo-runner --config runner-config.yaml daemon +docker run -e GITEA_INSTANCE_URL=http://192.168.8.18:3000 -e GITEA_RUNNER_REGISTRATION_TOKEN= -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/data:/data --name my_runner gitea/act_runner:nightly ``` -The workflows will run using the host docker srever +The `/data` directory inside the docker container contains the runner API keys after registration. +It must be persisted, otherwise the runner would try to register again, using the same, now defunct registration token. diff --git a/examples/kubernetes/README.md b/examples/kubernetes/README.md index d00cf1a..a8784b4 100644 --- a/examples/kubernetes/README.md +++ b/examples/kubernetes/README.md @@ -1,7 +1,13 @@ -## Kubernetes Docker in Docker Deployment +## Kubernetes Docker in Docker Deployment with `act_runner` Registers Kubernetes pod runners using [offline registration](https://forgejo.org/docs/v1.21/admin/actions/#offline-registration), allowing the scaling of runners as needed. NOTE: Docker in Docker (dind) requires elevated privileges on Kubernetes. The current way to achieve this is to set the pod `SecurityContext` to `privileged`. Keep in mind that this is a potential security issue that has the potential for a malicious application to break out of the container context. -[`dind-docker.yaml`](dind-docker.yaml) creates a deployment and secret for Kubernetes to act as a runner. The Docker credentials are re-generated each time the pod connects and does not need to be persisted. +Files in this directory: + +- [`dind-docker.yaml`](dind-docker.yaml) + How to create a Deployment and Secret for Kubernetes to act as a runner. The Docker credentials are re-generated each time the pod connects and does not need to be persisted. + +- [`rootless-docker.yaml`](rootless-docker.yaml) + How to create a rootless Deployment and Secret for Kubernetes to act as a runner. The Docker credentials are re-generated each time the pod connects and does not need to be persisted. diff --git a/examples/kubernetes/dind-docker.yaml b/examples/kubernetes/dind-docker.yaml index 534432d..92e46e9 100644 --- a/examples/kubernetes/dind-docker.yaml +++ b/examples/kubernetes/dind-docker.yaml @@ -1,5 +1,4 @@ # Secret data. -# You will need to retrive this from the web UI, and your Forgejo instance must be running v1.21+ # Alternatively, create this with # kubectl create secret generic runner-secret --from-literal=token=your_offline_token_here apiVersion: v1 @@ -13,20 +12,20 @@ apiVersion: apps/v1 kind: Deployment metadata: labels: - app: forgejo-runner - name: forgejo-runner + app: act-runner + name: act-runner spec: # Two replicas means that if one is busy, the other can pick up jobs. replicas: 2 selector: matchLabels: - app: forgejo-runner + app: act-runner strategy: {} template: metadata: creationTimestamp: null labels: - app: forgejo-runner + app: act-runner spec: restartPolicy: Always volumes: @@ -37,32 +36,24 @@ spec: # Initialise our configuration file using offline registration # https://forgejo.org/docs/v1.21/admin/actions/#offline-registration initContainers: - - name: runner-register - image: code.forgejo.org/forgejo/runner:3.2.0 - command: ["forgejo-runner", "register", "--no-interactive", "--token", $(RUNNER_SECRET), "--name", $(RUNNER_NAME), "--instance", $(FORGEJO_INSTANCE_URL)] - env: - - name: RUNNER_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: RUNNER_SECRET - valueFrom: - secretKeyRef: - name: runner-secret - key: token - - name: FORGEJO_INSTANCE_URL - value: http://forgejo-http.forgejo.svc.cluster.local:3000 - resources: - limits: - cpu: "0.50" - memory: "64Mi" - volumeMounts: - - name: runner-data - mountPath: /data + - name: runner-config-generation + image: code.forgejo.org/forgejo/runner:2.4.0 + command: [ "sh", "-c", "cd /data && forgejo-runner create-runner-file --instance $GITEA_INSTANCE_URL --secret $RUNNER_SECRET --connect" ] + env: + - name: RUNNER_SECRET + valueFrom: + secretKeyRef: + name: runner-secret + key: token + - name: GITEA_INSTANCE_URL + value: http://gitea-http.gitea.svc.cluster.local:3000 + volumeMounts: + - name: runner-data + mountPath: /data containers: - name: runner - image: code.forgejo.org/forgejo/runner:3.0.0 - command: ["sh", "-c", "while ! nc -z localhost 2376 /home/rootless/act_runner/config +``` + +- Create a new user-level`systemd` unit file as `/home/rootless/.config/systemd/user/act_runner.service` with the following contents: + +```bash + Description=Gitea Actions runner + Documentation=https://gitea.com/gitea/act_runner + After=docker.service + + [Service] + Environment=PATH=/home/rootless/bin:/sbin:/usr/sbin:/home/rootless/bin:/home/rootless/bin:/home/rootless/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games + Environment=DOCKER_HOST=unix:///run/user/1001/docker.sock + ExecStart=/usr/bin/act_runner daemon -c /home/rootless/act_runner/config + ExecReload=/bin/kill -s HUP $MAINPID + WorkingDirectory=/home/rootless/act_runner + TimeoutSec=0 + RestartSec=2 + Restart=always + StartLimitBurst=3 + StartLimitInterval=60s + LimitNOFILE=infinity + LimitNPROC=infinity + LimitCORE=infinity + TasksMax=infinity + Delegate=yes + Type=notify + NotifyAccess=all + KillMode=mixed + + [Install] + WantedBy=default.target +``` + +- Reboot + +After the system restarts, check that the`act_runner` is working and that the runner is connected to Gitea. + +````bash + systemctl --user status act_runner + journalctl --user -xeu act_runner diff --git a/go.mod b/go.mod index 07622ad..d72dbe7 100644 --- a/go.mod +++ b/go.mod @@ -1,27 +1,25 @@ module gitea.com/gitea/act_runner -go 1.21.13 - -toolchain go1.23.1 +go 1.21 require ( - code.gitea.io/actions-proto-go v0.4.0 - code.gitea.io/gitea-vet v0.2.3 - connectrpc.com/connect v1.17.0 - github.com/avast/retry-go/v4 v4.6.0 - github.com/docker/docker v25.0.6+incompatible - github.com/google/uuid v1.6.0 + code.gitea.io/actions-proto-go v0.3.1 + code.gitea.io/gitea-vet v0.2.3-0.20230113022436-2b1561217fa5 + github.com/avast/retry-go/v4 v4.5.0 + github.com/bufbuild/connect-go v1.10.0 + github.com/docker/docker v24.0.5+incompatible + github.com/google/uuid v1.3.0 github.com/joho/godotenv v1.5.1 - github.com/mattn/go-isatty v0.0.20 + github.com/mattn/go-isatty v0.0.19 github.com/nektos/act v0.2.49 github.com/sirupsen/logrus v1.9.3 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 - golang.org/x/term v0.24.0 - golang.org/x/time v0.6.0 - google.golang.org/protobuf v1.34.2 + github.com/spf13/cobra v1.7.0 + github.com/stretchr/testify v1.8.4 + golang.org/x/term v0.11.0 + golang.org/x/time v0.3.0 + google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 - gotest.tools/v3 v3.5.1 + gotest.tools/v3 v3.5.0 ) require ( @@ -29,31 +27,26 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect - github.com/cloudflare/circl v1.3.7 // indirect - github.com/containerd/containerd v1.7.13 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/creack/pty v1.1.21 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect + github.com/acomagu/bufpipe v1.0.4 // indirect + github.com/cloudflare/circl v1.3.3 // indirect + github.com/containerd/containerd v1.7.3 // indirect + github.com/creack/pty v1.1.18 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/distribution/reference v0.5.0 // indirect - github.com/docker/cli v25.0.3+incompatible // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect + github.com/docker/cli v24.0.5+incompatible // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.8.0 // indirect - github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/fatih/color v1.16.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.11.0 // indirect - github.com/go-logr/logr v1.3.0 // indirect - github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-git/go-billy/v5 v5.4.1 // indirect + github.com/go-git/go-git/v5 v5.8.1 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -61,45 +54,41 @@ require ( github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect - github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/compress v1.16.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/buildkit v0.13.2 // indirect - github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/buildkit v0.12.1 // indirect + github.com/moby/patternmatcher v0.5.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/user v0.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc5 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/runc v1.1.8 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rhysd/actionlint v1.6.27 // indirect - github.com/rivo/uniseg v0.4.7 // indirect - github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/rhysd/actionlint v1.6.25 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/robfig/cron v1.2.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect - github.com/skeema/knownhosts v1.2.1 // indirect + github.com/skeema/knownhosts v1.2.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/objx v0.5.1 // indirect github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect - go.etcd.io/bbolt v1.3.9 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.21.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/tools v0.14.0 // indirect + go.etcd.io/bbolt v1.3.7 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/tools v0.12.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) -replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.21.3 +replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.10.0 diff --git a/go.sum b/go.sum index 498a542..29be466 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,13 @@ -code.forgejo.org/forgejo/act v1.21.3 h1:EeJbrz0aar2QhIcBlOW5gjK1rjrQxcAvQSPpG/R1h5w= -code.forgejo.org/forgejo/act v1.21.3/go.mod h1:+PcvJ9iv+NTFeJSh79ra9Jbk9l0vvyA9D9me5/dbxYM= -code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU= -code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas= -code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI= -code.gitea.io/gitea-vet v0.2.3/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= -connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk= -connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8= +code.forgejo.org/forgejo/act v1.10.0 h1:vvF8V0t8CC95wttzRnCRHFS3tW+HVuzxCJXXolNDdBU= +code.forgejo.org/forgejo/act v1.10.0/go.mod h1:tfannUyz3cgmq1P1o69KW1AMB1aSlNOMzlswHkRjzcQ= +code.gitea.io/actions-proto-go v0.3.1 h1:PMyiQtBKb8dNnpEO2R5rcZdXSis+UQZVo/SciMtR1aU= +code.gitea.io/actions-proto-go v0.3.1/go.mod h1:00ys5QDo1iHN1tHNvvddAcy2W/g+425hQya1cCSvq9A= +code.gitea.io/gitea-vet v0.2.3-0.20230113022436-2b1561217fa5 h1:daBEK2GQeqGikJESctP5Cu1i33z5ztAD4kyQWiw185M= +code.gitea.io/gitea-vet v0.2.3-0.20230113022436-2b1561217fa5/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= @@ -17,87 +15,76 @@ github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF0 github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= -github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= -github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= +github.com/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= +github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs= +github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/avast/retry-go/v4 v4.6.0 h1:K9xNA+KeB8HHc2aWFuLb25Offp+0iVRXEvFx8IinRJA= -github.com/avast/retry-go/v4 v4.6.0/go.mod h1:gvWlPhBVsvBbLkVGDg/KwvBv0bEkCOLRRSHKIr2PyOE= +github.com/avast/retry-go/v4 v4.5.0 h1:QoRAZZ90cj5oni2Lsgl2GW8mNTnUCnmpx/iKpwVisHg= +github.com/avast/retry-go/v4 v4.5.0/go.mod h1:7hLEXp0oku2Nir2xBAsg0PTphp9z71bN5Aq1fboC3+I= +github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg= +github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= -github.com/containerd/containerd v1.7.13 h1:wPYKIeGMN8vaggSKuV1X0wZulpMz4CrgEsZdaCyB6Is= -github.com/containerd/containerd v1.7.13/go.mod h1:zT3up6yTRfEUa6+GsITYIJNgSVL9NQ4x4h1RPzk0Wu4= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= -github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= -github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= +github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v25.0.3+incompatible h1:KLeNs7zws74oFuVhgZQ5ONGZiXUUdgsdy6/EsX/6284= -github.com/docker/cli v25.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= -github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= -github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/cli v24.0.5+incompatible h1:WeBimjvS0eKdH4Ygx+ihVq1Q++xg36M/rMi4aXAvodc= +github.com/docker/cli v24.0.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= +github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8= github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= +github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= -github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= -github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= +github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= +github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= +github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -114,42 +101,44 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4 github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= +github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/buildkit v0.13.2 h1:nXNszM4qD9E7QtG7bFWPnDI1teUQFQglBzon/IU3SzI= -github.com/moby/buildkit v0.13.2/go.mod h1:2cyVOv9NoHM7arphK9ZfHIWKn9YVZRFd1wXB8kKmEzY= -github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= -github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/buildkit v0.12.1 h1:vvMG7EZYCiQZpTtXQkvyeyj7HzT1JHhDWj+/aiGIzLM= +github.com/moby/buildkit v0.12.1/go.mod h1:adB4y0SxxX8trnrY+oEulb48ODLqPO6pKMF0ppGcCoI= +github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= -github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd h1:aY7OQNf2XqY/JQ6qREWamhI/81os/agb2BAGpcx5yWI= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= -github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.8 h1:zICRlc+C1XzivLc3nzE+cbJV4LIi8tib6YG0MqC6OqA= +github.com/opencontainers/runc v1.1.8/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= @@ -158,36 +147,41 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rhysd/actionlint v1.6.27 h1:xxwe8YmveBcC8lydW6GoHMGmB6H/MTqUU60F2p10wjw= -github.com/rhysd/actionlint v1.6.27/go.mod h1:m2nFUjAnOrxCMXuOMz9evYBRCLUsMnKY2IJl/N5umbk= +github.com/rhysd/actionlint v1.6.25 h1:0Is99a51w1iocdxKUzNYiBNwjoSlO2Klqzll98joVj4= +github.com/rhysd/actionlint v1.6.25/go.mod h1:Q+MtZKm1MdmJ9woOSKxLscMW7kU44/PShvjNy5ZKHA8= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= -github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= -github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= +github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= +github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a h1:oIi7H/bwFUYKYhzKbHc+3MvHRWqhQwXVB4LweLMiVy0= github.com/timshannon/bolthold v0.0.0-20210913165410-232392fc8a6a/go.mod h1:iSvujNDmpZ6eQX+bg/0X3lF7LEmZ8N77g2a/J/+Zt2U= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= @@ -204,24 +198,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= -go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= 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= @@ -229,14 +207,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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= @@ -247,15 +225,15 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= 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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= 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= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -274,15 +252,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= 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.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -290,10 +268,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= -golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= @@ -301,21 +279,15 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k= -google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -328,5 +300,5 @@ 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= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/internal/app/cmd/create-runner-file.go b/internal/app/cmd/create-runner-file.go index a972624..c28a74b 100644 --- a/internal/app/cmd/create-runner-file.go +++ b/internal/app/cmd/create-runner-file.go @@ -9,7 +9,7 @@ import ( "os" pingv1 "code.gitea.io/actions-proto-go/ping/v1" - "connectrpc.com/connect" + "github.com/bufbuild/connect-go" gouuid "github.com/google/uuid" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -38,7 +38,7 @@ func createRunnerFileCmd(ctx context.Context, configFile *string) *cobra.Command cmd.Flags().BoolVar(&argsVar.Connect, "connect", false, "tries to connect to the instance using the secret (Forgejo v1.21 instance or greater)") cmd.Flags().StringVar(&argsVar.InstanceAddr, "instance", "", "Forgejo instance address") cmd.MarkFlagRequired("instance") - cmd.Flags().StringVar(&argsVar.Secret, "secret", "", "secret shared with the Forgejo instance via forgejo-cli actions register") + cmd.Flags().StringVar(&argsVar.Secret, "secret", "", "secret shared with the Frogejo instance via forgejo-cli actions register") cmd.MarkFlagRequired("secret") cmd.Flags().StringVar(&argsVar.Name, "name", "", "Runner name") diff --git a/internal/app/cmd/create-runner-file_test.go b/internal/app/cmd/create-runner-file_test.go index 4f3acb8..e55a3d7 100644 --- a/internal/app/cmd/create-runner-file_test.go +++ b/internal/app/cmd/create-runner-file_test.go @@ -9,10 +9,10 @@ import ( "testing" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "connectrpc.com/connect" "gitea.com/gitea/act_runner/internal/pkg/client" "gitea.com/gitea/act_runner/internal/pkg/config" "gitea.com/gitea/act_runner/internal/pkg/ver" + "github.com/bufbuild/connect-go" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" diff --git a/internal/app/cmd/daemon.go b/internal/app/cmd/daemon.go index a613546..a2a3974 100644 --- a/internal/app/cmd/daemon.go +++ b/internal/app/cmd/daemon.go @@ -13,7 +13,7 @@ import ( "strconv" "strings" - "connectrpc.com/connect" + "github.com/bufbuild/connect-go" "github.com/mattn/go-isatty" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -45,8 +45,6 @@ func runDaemon(ctx context.Context, configFile *string) func(cmd *cobra.Command, return fmt.Errorf("failed to load registration file: %w", err) } - cfg.Tune(reg.Address) - lbls := reg.Labels if len(cfg.Runner.Labels) > 0 { lbls = cfg.Runner.Labels @@ -103,15 +101,14 @@ func runDaemon(ctx context.Context, configFile *string) func(cmd *cobra.Command, resp, err := runner.Declare(ctx, ls.Names()) if err != nil && connect.CodeOf(err) == connect.CodeUnimplemented { // Gitea instance is older version. skip declare step. - log.Warn("Because the Forgejo instance is an old version, skipping declaring the labels and version.") + log.Warn("Because the Forgejo instance is an old version, skip declare labels and version.") } else if err != nil { log.WithError(err).Error("fail to invoke Declare") return err } else { - log.Infof("runner: %s, with version: %s, with labels: %v, declared successfully", + log.Infof("runner: %s, with version: %s, with labels: %v, declare successfully", resp.Msg.Runner.Name, resp.Msg.Runner.Version, resp.Msg.Runner.Labels) - // if declared successfully, override the labels in the.runner file with valid labels in the config file (if specified) - runner.Update(ctx, ls) + // if declare successfully, override the labels in the.runner file with valid labels in the config file (if specified) reg.Labels = ls.ToStrings() if err := config.SaveRegistration(cfg.Runner.File, reg); err != nil { return fmt.Errorf("failed to save runner config: %w", err) @@ -120,18 +117,8 @@ func runDaemon(ctx context.Context, configFile *string) func(cmd *cobra.Command, poller := poll.New(cfg, cli, runner) - go poller.Poll() + poller.Poll(ctx) - <-ctx.Done() - log.Infof("runner: %s shutdown initiated, waiting [runner].shutdown_timeout=%s for running jobs to complete before shutting down", resp.Msg.Runner.Name, cfg.Runner.ShutdownTimeout) - - ctx, cancel := context.WithTimeout(context.Background(), cfg.Runner.ShutdownTimeout) - defer cancel() - - err = poller.Shutdown(ctx) - if err != nil { - log.Warnf("runner: %s cancelled in progress jobs during shutdown", resp.Msg.Runner.Name) - } return nil } } diff --git a/internal/app/cmd/exec.go b/internal/app/cmd/exec.go index 3e111fe..1092fac 100644 --- a/internal/app/cmd/exec.go +++ b/internal/app/cmd/exec.go @@ -58,7 +58,6 @@ type executeArgs struct { image string cacheHandler *artifactcache.Handler network string - enableIPv6 bool githubInstance string } @@ -403,13 +402,12 @@ func runExec(ctx context.Context, execArgs *executeArgs) func(cmd *cobra.Command ArtifactServerPort: execArgs.artifactServerPort, ArtifactServerAddr: execArgs.artifactServerAddr, NoSkipCheckout: execArgs.noSkipCheckout, - // PresetGitHubContext: preset, - // EventJSON: string(eventJSON), - ContainerNamePrefix: fmt.Sprintf("FORGEJO-ACTIONS-TASK-%s", eventName), - ContainerMaxLifetime: maxLifetime, - ContainerNetworkMode: container.NetworkMode(execArgs.network), - ContainerNetworkEnableIPv6: execArgs.enableIPv6, - DefaultActionInstance: execArgs.defaultActionsURL, + // PresetGitHubContext: preset, + // EventJSON: string(eventJSON), + ContainerNamePrefix: fmt.Sprintf("FORGEJO-ACTIONS-TASK-%s", eventName), + ContainerMaxLifetime: maxLifetime, + ContainerNetworkMode: container.NetworkMode(execArgs.network), + DefaultActionInstance: execArgs.defaultActionsURL, PlatformPicker: func(_ []string) string { return execArgs.image }, @@ -486,9 +484,8 @@ func loadExecCmd(ctx context.Context) *cobra.Command { execCmd.PersistentFlags().BoolVarP(&execArg.noSkipCheckout, "no-skip-checkout", "", false, "Do not skip actions/checkout") execCmd.PersistentFlags().BoolVarP(&execArg.debug, "debug", "d", false, "enable debug log") execCmd.PersistentFlags().BoolVarP(&execArg.dryrun, "dryrun", "n", false, "dryrun mode") - execCmd.PersistentFlags().StringVarP(&execArg.image, "image", "i", "node:20-bullseye", "Docker image to use. Use \"-self-hosted\" to run directly on the host.") + execCmd.PersistentFlags().StringVarP(&execArg.image, "image", "i", "node:16-bullseye", "docker image to use") execCmd.PersistentFlags().StringVarP(&execArg.network, "network", "", "", "Specify the network to which the container will connect") - execCmd.PersistentFlags().BoolVarP(&execArg.enableIPv6, "enable-ipv6", "6", false, "Create network with IPv6 enabled.") execCmd.PersistentFlags().StringVarP(&execArg.githubInstance, "gitea-instance", "", "", "Gitea instance to use.") return execCmd diff --git a/internal/app/cmd/register.go b/internal/app/cmd/register.go index 803511a..d5ee299 100644 --- a/internal/app/cmd/register.go +++ b/internal/app/cmd/register.go @@ -15,7 +15,7 @@ import ( pingv1 "code.gitea.io/actions-proto-go/ping/v1" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "connectrpc.com/connect" + "github.com/bufbuild/connect-go" "github.com/mattn/go-isatty" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -91,7 +91,7 @@ const ( ) var defaultLabels = []string{ - "docker:docker://node:20-bullseye", + "docker:docker://node:16-bullseye", } type registerInputs struct { @@ -176,7 +176,7 @@ func (r *registerInputs) assignToNext(stage registerStage, value string, cfg *co } if validateLabels(r.Labels) != nil { - log.Infoln("Invalid labels, please input again, leave blank to use the default labels (for example, ubuntu-20.04:docker://node:20-bookworm,ubuntu-18.04:docker://node:20-bookworm)") + log.Infoln("Invalid labels, please input again, leave blank to use the default labels (for example, ubuntu-20.04:docker://node:16-bullseye,ubuntu-18.04:docker://node:16-buster,linux_arm:host)") return StageInputLabels } return StageWaitingForRegistration @@ -240,7 +240,7 @@ func printStageHelp(stage registerStage) { hostname, _ := os.Hostname() log.Infof("Enter the runner name (if set empty, use hostname: %s):\n", hostname) case StageInputLabels: - log.Infoln("Enter the runner labels, leave blank to use the default labels (comma-separated, for example, ubuntu-20.04:docker://node:20-bookworm,ubuntu-18.04:docker://node:20-bookworm):") + log.Infoln("Enter the runner labels, leave blank to use the default labels (comma-separated, for example, ubuntu-20.04:docker://node:16-bullseye,ubuntu-18.04:docker://node:16-buster,linux_arm:host):") case StageWaitingForRegistration: log.Infoln("Waiting for registration...") } diff --git a/internal/app/poll/poller.go b/internal/app/poll/poller.go index cc89fa5..f79e98e 100644 --- a/internal/app/poll/poller.go +++ b/internal/app/poll/poller.go @@ -11,7 +11,7 @@ import ( "sync/atomic" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "connectrpc.com/connect" + "github.com/bufbuild/connect-go" log "github.com/sirupsen/logrus" "golang.org/x/time/rate" @@ -20,100 +20,49 @@ import ( "gitea.com/gitea/act_runner/internal/pkg/config" ) -const PollerID = "PollerID" - -type Poller interface { - Poll() - Shutdown(ctx context.Context) error -} - -type poller struct { +type Poller struct { client client.Client - runner run.RunnerInterface + runner *run.Runner cfg *config.Config tasksVersion atomic.Int64 // tasksVersion used to store the version of the last task fetched from the Gitea. - - pollingCtx context.Context - shutdownPolling context.CancelFunc - - jobsCtx context.Context - shutdownJobs context.CancelFunc - - done chan any } -func New(cfg *config.Config, client client.Client, runner run.RunnerInterface) Poller { - return (&poller{}).init(cfg, client, runner) +func New(cfg *config.Config, client client.Client, runner *run.Runner) *Poller { + return &Poller{ + client: client, + runner: runner, + cfg: cfg, + } } -func (p *poller) init(cfg *config.Config, client client.Client, runner run.RunnerInterface) Poller { - pollingCtx, shutdownPolling := context.WithCancel(context.Background()) - - jobsCtx, shutdownJobs := context.WithCancel(context.Background()) - - done := make(chan any) - - p.client = client - p.runner = runner - p.cfg = cfg - - p.pollingCtx = pollingCtx - p.shutdownPolling = shutdownPolling - - p.jobsCtx = jobsCtx - p.shutdownJobs = shutdownJobs - p.done = done - - return p -} - -func (p *poller) Poll() { +func (p *Poller) Poll(ctx context.Context) { limiter := rate.NewLimiter(rate.Every(p.cfg.Runner.FetchInterval), 1) wg := &sync.WaitGroup{} for i := 0; i < p.cfg.Runner.Capacity; i++ { wg.Add(1) - go p.poll(i, wg, limiter) + go p.poll(ctx, wg, limiter) } wg.Wait() - - // signal the poller is finished - close(p.done) } -func (p *poller) Shutdown(ctx context.Context) error { - p.shutdownPolling() - - select { - case <-p.done: - log.Trace("all jobs are complete") - return nil - - case <-ctx.Done(): - log.Trace("forcing the jobs to shutdown") - p.shutdownJobs() - <-p.done - log.Trace("all jobs have been shutdown") - return ctx.Err() - } -} - -func (p *poller) poll(id int, wg *sync.WaitGroup, limiter *rate.Limiter) { - log.Infof("[poller %d] launched", id) +func (p *Poller) poll(ctx context.Context, wg *sync.WaitGroup, limiter *rate.Limiter) { defer wg.Done() for { - if err := limiter.Wait(p.pollingCtx); err != nil { - log.Infof("[poller %d] shutdown", id) + if err := limiter.Wait(ctx); err != nil { + if ctx.Err() != nil { + log.WithError(err).Debug("limiter wait failed") + } return } - task, ok := p.fetchTask(p.pollingCtx) + task, ok := p.fetchTask(ctx) if !ok { continue } - p.runTaskWithRecover(p.jobsCtx, task) + p.runTaskWithRecover(ctx, task) } } -func (p *poller) runTaskWithRecover(ctx context.Context, task *runnerv1.Task) { +func (p *Poller) runTaskWithRecover(ctx context.Context, task *runnerv1.Task) { defer func() { if r := recover(); r != nil { err := fmt.Errorf("panic: %v", r) @@ -126,7 +75,7 @@ func (p *poller) runTaskWithRecover(ctx context.Context, task *runnerv1.Task) { } } -func (p *poller) fetchTask(ctx context.Context) (*runnerv1.Task, bool) { +func (p *Poller) fetchTask(ctx context.Context) (*runnerv1.Task, bool) { reqCtx, cancel := context.WithTimeout(ctx, p.cfg.Runner.FetchTimeout) defer cancel() @@ -136,15 +85,10 @@ func (p *poller) fetchTask(ctx context.Context) (*runnerv1.Task, bool) { TasksVersion: v, })) if errors.Is(err, context.DeadlineExceeded) { - log.Trace("deadline exceeded") err = nil } if err != nil { - if errors.Is(err, context.Canceled) { - log.WithError(err).Debugf("shutdown, fetch task canceled") - } else { - log.WithError(err).Error("failed to fetch task") - } + log.WithError(err).Error("failed to fetch task") return nil, false } diff --git a/internal/app/poll/poller_test.go b/internal/app/poll/poller_test.go deleted file mode 100644 index 04b1a84..0000000 --- a/internal/app/poll/poller_test.go +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright The Forgejo Authors. -// SPDX-License-Identifier: MIT - -package poll - -import ( - "context" - "fmt" - "testing" - "time" - - "connectrpc.com/connect" - - "code.gitea.io/actions-proto-go/ping/v1/pingv1connect" - runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "code.gitea.io/actions-proto-go/runner/v1/runnerv1connect" - "gitea.com/gitea/act_runner/internal/pkg/config" - - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" -) - -type mockPoller struct { - poller -} - -func (o *mockPoller) Poll() { - o.poller.Poll() -} - -type mockClient struct { - pingv1connect.PingServiceClient - runnerv1connect.RunnerServiceClient - - sleep time.Duration - cancel bool - err error - noTask bool -} - -func (o mockClient) Address() string { - return "" -} - -func (o mockClient) Insecure() bool { - return true -} - -func (o *mockClient) FetchTask(ctx context.Context, req *connect.Request[runnerv1.FetchTaskRequest]) (*connect.Response[runnerv1.FetchTaskResponse], error) { - if o.sleep > 0 { - select { - case <-ctx.Done(): - log.Trace("fetch task done") - return nil, context.DeadlineExceeded - case <-time.After(o.sleep): - log.Trace("slept") - return nil, fmt.Errorf("unexpected") - } - } - if o.cancel { - return nil, context.Canceled - } - if o.err != nil { - return nil, o.err - } - task := &runnerv1.Task{} - if o.noTask { - task = nil - o.noTask = false - } - - return connect.NewResponse(&runnerv1.FetchTaskResponse{ - Task: task, - TasksVersion: int64(1), - }), nil -} - -type mockRunner struct { - cfg *config.Runner - log chan string - panics bool - err error -} - -func (o *mockRunner) Run(ctx context.Context, task *runnerv1.Task) error { - o.log <- "runner starts" - if o.panics { - log.Trace("panics") - o.log <- "runner panics" - o.panics = false - panic("whatever") - } - if o.err != nil { - log.Trace("error") - o.log <- "runner error" - err := o.err - o.err = nil - return err - } - for { - select { - case <-ctx.Done(): - log.Trace("shutdown") - o.log <- "runner shutdown" - return nil - case <-time.After(o.cfg.Timeout): - log.Trace("after") - o.log <- "runner timeout" - return nil - } - } -} - -func setTrace(t *testing.T) { - t.Helper() - log.SetReportCaller(true) - log.SetLevel(log.TraceLevel) -} - -func TestPoller_New(t *testing.T) { - p := New(&config.Config{}, &mockClient{}, &mockRunner{}) - assert.NotNil(t, p) -} - -func TestPoller_Runner(t *testing.T) { - setTrace(t) - for _, testCase := range []struct { - name string - timeout time.Duration - noTask bool - panics bool - err error - expected string - contextTimeout time.Duration - }{ - { - name: "Simple", - timeout: 10 * time.Second, - expected: "runner shutdown", - }, - { - name: "Panics", - timeout: 10 * time.Second, - panics: true, - expected: "runner panics", - }, - { - name: "Error", - timeout: 10 * time.Second, - err: fmt.Errorf("ERROR"), - expected: "runner error", - }, - { - name: "PollTaskError", - timeout: 10 * time.Second, - noTask: true, - expected: "runner shutdown", - }, - { - name: "ShutdownTimeout", - timeout: 1 * time.Second, - contextTimeout: 1 * time.Minute, - expected: "runner timeout", - }, - } { - t.Run(testCase.name, func(t *testing.T) { - runnerLog := make(chan string, 3) - configRunner := config.Runner{ - FetchInterval: 1, - Capacity: 1, - Timeout: testCase.timeout, - } - p := &mockPoller{} - p.init( - &config.Config{ - Runner: configRunner, - }, - &mockClient{ - noTask: testCase.noTask, - }, - &mockRunner{ - cfg: &configRunner, - log: runnerLog, - panics: testCase.panics, - err: testCase.err, - }) - go p.Poll() - assert.Equal(t, "runner starts", <-runnerLog) - var ctx context.Context - var cancel context.CancelFunc - if testCase.contextTimeout > 0 { - ctx, cancel = context.WithTimeout(context.Background(), testCase.contextTimeout) - defer cancel() - } else { - ctx, cancel = context.WithCancel(context.Background()) - cancel() - } - p.Shutdown(ctx) - <-p.done - assert.Equal(t, testCase.expected, <-runnerLog) - }) - } -} - -func TestPoller_Fetch(t *testing.T) { - setTrace(t) - for _, testCase := range []struct { - name string - noTask bool - sleep time.Duration - err error - cancel bool - success bool - }{ - { - name: "Success", - success: true, - }, - { - name: "Timeout", - sleep: 100 * time.Millisecond, - }, - { - name: "Canceled", - cancel: true, - }, - { - name: "NoTask", - noTask: true, - }, - { - name: "Error", - err: fmt.Errorf("random error"), - }, - } { - t.Run(testCase.name, func(t *testing.T) { - configRunner := config.Runner{ - FetchTimeout: 1 * time.Millisecond, - } - p := &mockPoller{} - p.init( - &config.Config{ - Runner: configRunner, - }, - &mockClient{ - sleep: testCase.sleep, - cancel: testCase.cancel, - noTask: testCase.noTask, - err: testCase.err, - }, - &mockRunner{}, - ) - task, ok := p.fetchTask(context.Background()) - if testCase.success { - assert.True(t, ok) - assert.NotNil(t, task) - } else { - assert.False(t, ok) - assert.Nil(t, task) - } - }) - } -} diff --git a/internal/app/run/runner.go b/internal/app/run/runner.go index e8654b6..477fc93 100644 --- a/internal/app/run/runner.go +++ b/internal/app/run/runner.go @@ -13,7 +13,7 @@ import ( "time" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "connectrpc.com/connect" + "github.com/bufbuild/connect-go" "github.com/docker/docker/api/types/container" "github.com/nektos/act/pkg/artifactcache" "github.com/nektos/act/pkg/common" @@ -41,10 +41,6 @@ type Runner struct { runningTasks sync.Map } -type RunnerInterface interface { - Run(ctx context.Context, task *runnerv1.Task) error -} - func NewRunner(cfg *config.Config, reg *config.Registration, cli client.Client) *Runner { ls := labels.Labels{} for _, v := range reg.Labels { @@ -85,7 +81,6 @@ func NewRunner(cfg *config.Config, reg *config.Registration, cli client.Client) // set artifact gitea api artifactGiteaAPI := strings.TrimSuffix(cli.Address(), "/") + "/api/actions_pipeline/" envs["ACTIONS_RUNTIME_URL"] = artifactGiteaAPI - envs["ACTIONS_RESULTS_URL"] = strings.TrimSuffix(cli.Address(), "/") // Set specific environments to distinguish between Gitea and GitHub envs["GITEA_ACTIONS"] = "true" @@ -109,7 +104,7 @@ func (r *Runner) Run(ctx context.Context, task *runnerv1.Task) error { ctx, cancel := context.WithTimeout(ctx, r.cfg.Runner.Timeout) defer cancel() - reporter := report.NewReporter(ctx, cancel, r.client, task, r.cfg.Runner.ReportInterval) + reporter := report.NewReporter(ctx, cancel, r.client, task) var runErr error defer func() { lastWords := "" @@ -174,12 +169,8 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report. preset.Token = t } - giteaRuntimeToken := taskContext["gitea_runtime_token"].GetStringValue() - if giteaRuntimeToken == "" { - // use task token to action api token for previous Gitea Server Versions - giteaRuntimeToken = preset.Token - } - r.envs["ACTIONS_RUNTIME_TOKEN"] = giteaRuntimeToken + // use task token to action api token + r.envs["ACTIONS_RUNTIME_TOKEN"] = preset.Token eventJSON, err := json.Marshal(preset.Event) if err != nil { @@ -191,13 +182,6 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report. maxLifetime = time.Until(deadline) } - var inputs map[string]string - if preset.EventName == "workflow_dispatch" { - if inputsRaw, ok := preset.Event["inputs"]; ok { - inputs, _ = inputsRaw.(map[string]string) - } - } - runnerConfig := &runner.Config{ // On Linux, Workdir will be like "///" // On Windows, Workdir will be like "\\\" @@ -205,31 +189,28 @@ func (r *Runner) run(ctx context.Context, task *runnerv1.Task, reporter *report. BindWorkdir: false, ActionCacheDir: filepath.FromSlash(r.cfg.Host.WorkdirParent), - ReuseContainers: false, - ForcePull: r.cfg.Container.ForcePull, - ForceRebuild: false, - LogOutput: true, - JSONLogger: false, - Env: r.envs, - Secrets: task.Secrets, - GitHubInstance: strings.TrimSuffix(r.client.Address(), "/"), - AutoRemove: true, - NoSkipCheckout: true, - PresetGitHubContext: preset, - EventJSON: string(eventJSON), - ContainerNamePrefix: fmt.Sprintf("GITEA-ACTIONS-TASK-%d", task.Id), - ContainerMaxLifetime: maxLifetime, - ContainerNetworkMode: container.NetworkMode(r.cfg.Container.Network), - ContainerNetworkEnableIPv6: r.cfg.Container.EnableIPv6, - ContainerOptions: r.cfg.Container.Options, - ContainerDaemonSocket: r.cfg.Container.DockerHost, - Privileged: r.cfg.Container.Privileged, - DefaultActionInstance: taskContext["gitea_default_actions_url"].GetStringValue(), - PlatformPicker: r.labels.PickPlatform, - Vars: task.Vars, - ValidVolumes: r.cfg.Container.ValidVolumes, - InsecureSkipTLS: r.cfg.Runner.Insecure, - Inputs: inputs, + ReuseContainers: false, + ForcePull: r.cfg.Container.ForcePull, + ForceRebuild: false, + LogOutput: true, + JSONLogger: false, + Env: r.envs, + Secrets: task.Secrets, + GitHubInstance: strings.TrimSuffix(r.client.Address(), "/"), + AutoRemove: true, + NoSkipCheckout: true, + PresetGitHubContext: preset, + EventJSON: string(eventJSON), + ContainerNamePrefix: fmt.Sprintf("GITEA-ACTIONS-TASK-%d", task.Id), + ContainerMaxLifetime: maxLifetime, + ContainerNetworkMode: container.NetworkMode(r.cfg.Container.Network), + ContainerOptions: r.cfg.Container.Options, + ContainerDaemonSocket: r.cfg.Container.DockerHost, + Privileged: r.cfg.Container.Privileged, + DefaultActionInstance: taskContext["gitea_default_actions_url"].GetStringValue(), + PlatformPicker: r.labels.PickPlatform, + Vars: task.Vars, + ValidVolumes: r.cfg.Container.ValidVolumes, } rr, err := runner.New(runnerConfig) @@ -254,7 +235,3 @@ func (r *Runner) Declare(ctx context.Context, labels []string) (*connect.Respons Labels: labels, })) } - -func (r *Runner) Update(ctx context.Context, labels labels.Labels) { - r.labels = labels -} diff --git a/internal/app/run/runner_test.go b/internal/app/run/runner_test.go deleted file mode 100644 index 0145c70..0000000 --- a/internal/app/run/runner_test.go +++ /dev/null @@ -1,37 +0,0 @@ -package run - -import ( - "context" - "testing" - - "gitea.com/gitea/act_runner/internal/pkg/labels" - "github.com/stretchr/testify/assert" -) - -func TestLabelUpdate(t *testing.T) { - ctx := context.Background() - ls := labels.Labels{} - - initialLabel, err := labels.Parse("testlabel:docker://alpine") - assert.NoError(t, err) - ls = append(ls, initialLabel) - - newLs := labels.Labels{} - - newLabel, err := labels.Parse("next label:host") - assert.NoError(t, err) - newLs = append(newLs, initialLabel) - newLs = append(newLs, newLabel) - - runner := Runner{ - labels: ls, - } - - assert.Contains(t, runner.labels, initialLabel) - assert.NotContains(t, runner.labels, newLabel) - - runner.Update(ctx, newLs) - - assert.Contains(t, runner.labels, initialLabel) - assert.Contains(t, runner.labels, newLabel) -} diff --git a/internal/app/run/workflow_test.go b/internal/app/run/workflow_test.go index 4ab31b1..c7598db 100644 --- a/internal/app/run/workflow_test.go +++ b/internal/app/run/workflow_test.go @@ -19,7 +19,7 @@ func Test_generateWorkflow(t *testing.T) { tests := []struct { name string args args - assert func(t *testing.T, wf *model.Workflow, err error) + assert func(t *testing.T, wf *model.Workflow) want1 string wantErr bool }{ @@ -56,41 +56,19 @@ jobs: }, }, }, - assert: func(t *testing.T, wf *model.Workflow, err error) { + assert: func(t *testing.T, wf *model.Workflow) { assert.DeepEqual(t, wf.GetJob("job9").Needs(), []string{"job1", "job2"}) }, want1: "job9", wantErr: false, }, - { - name: "valid YAML syntax in top level env but wrong value type", - args: args{ - task: &runnerv1.Task{ - WorkflowPayload: []byte(` -on: push - -env: - value: {{ }} -`), - }, - }, - assert: func(t *testing.T, wf *model.Workflow, err error) { - require.Nil(t, wf) - assert.ErrorContains(t, err, "cannot unmarshal") - }, - wantErr: true, - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got, got1, err := generateWorkflow(tt.args.task) - if tt.wantErr { - require.Error(t, err) - } else { - require.NoError(t, err) - assert.Equal(t, got1, tt.want1) - } - tt.assert(t, got, err) + require.NoError(t, err) + tt.assert(t, got) + assert.Equal(t, got1, tt.want1) }) } } diff --git a/internal/pkg/client/http.go b/internal/pkg/client/http.go index d365a77..9f659df 100644 --- a/internal/pkg/client/http.go +++ b/internal/pkg/client/http.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/actions-proto-go/ping/v1/pingv1connect" "code.gitea.io/actions-proto-go/runner/v1/runnerv1connect" - "connectrpc.com/connect" + "github.com/bufbuild/connect-go" ) func getHTTPClient(endpoint string, insecure bool) *http.Client { diff --git a/internal/pkg/client/mocks/Client.go b/internal/pkg/client/mocks/Client.go index a8bfdb1..d80992d 100644 --- a/internal/pkg/client/mocks/Client.go +++ b/internal/pkg/client/mocks/Client.go @@ -5,7 +5,7 @@ package mocks import ( context "context" - connect "connectrpc.com/connect" + connect "github.com/bufbuild/connect-go" mock "github.com/stretchr/testify/mock" diff --git a/internal/pkg/config/config.example.yaml b/internal/pkg/config/config.example.yaml index 32dfb68..5c185f2 100644 --- a/internal/pkg/config/config.example.yaml +++ b/internal/pkg/config/config.example.yaml @@ -23,22 +23,14 @@ runner: # Please note that the Forgejo instance also has a timeout (3h by default) for the job. # So the job could be stopped by the Forgejo instance if it's timeout is shorter than this. timeout: 3h - # The timeout for the runner to wait for running jobs to finish when - # shutting down because a TERM or INT signal has been received. Any - # running jobs that haven't finished after this timeout will be - # cancelled. - # If unset or zero the jobs will be cancelled immediately. - shutdown_timeout: 3h - # Whether skip verifying the TLS certificate of the instance. + # Whether skip verifying the TLS certificate of the Forgejo instance. insecure: false # The timeout for fetching the job from the Forgejo instance. fetch_timeout: 5s # The interval for fetching the job from the Forgejo instance. fetch_interval: 2s - # The interval for reporting the job status and logs to the Forgejo instance. - report_interval: 1s # The labels of a runner are used to determine which jobs the runner can run, and how to run them. - # Like: ["macos-arm64:host", "ubuntu-latest:docker://node:20-bookworm", "ubuntu-22.04:docker://node:20-bookworm"] + # Like: ["macos-arm64:host", "ubuntu-latest:docker://node:16-bullseye", "ubuntu-22.04:docker://node:16-bullseye"] # If it's empty when registering, it will ask for inputting labels. # If it's empty when execute `deamon`, will use labels in `.runner` file. labels: [] @@ -66,9 +58,6 @@ container: # Could be host, bridge or the name of a custom network. # If it's empty, create a network automatically. network: "" - # Whether to create networks with IPv6 enabled. Requires the Docker daemon to be set up accordingly. - # Only takes effect if "network" is set to "". - enable_ipv6: false # Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker). privileged: false # And other options to be used when the container is started (eg, --add-host=my.forgejo.url:host-gateway). diff --git a/internal/pkg/config/config.go b/internal/pkg/config/config.go index a1536b3..46fd059 100644 --- a/internal/pkg/config/config.go +++ b/internal/pkg/config/config.go @@ -21,17 +21,15 @@ type Log struct { // Runner represents the configuration for the runner. type Runner struct { - File string `yaml:"file"` // File specifies the file path for the runner. - Capacity int `yaml:"capacity"` // Capacity specifies the capacity of the runner. - Envs map[string]string `yaml:"envs"` // Envs stores environment variables for the runner. - EnvFile string `yaml:"env_file"` // EnvFile specifies the path to the file containing environment variables for the runner. - Timeout time.Duration `yaml:"timeout"` // Timeout specifies the duration for runner timeout. - ShutdownTimeout time.Duration `yaml:"shutdown_timeout"` // ShutdownTimeout specifies the duration to wait for running jobs to complete during a shutdown of the runner. - Insecure bool `yaml:"insecure"` // Insecure indicates whether the runner operates in an insecure mode. - FetchTimeout time.Duration `yaml:"fetch_timeout"` // FetchTimeout specifies the timeout duration for fetching resources. - FetchInterval time.Duration `yaml:"fetch_interval"` // FetchInterval specifies the interval duration for fetching resources. - ReportInterval time.Duration `yaml:"report_interval"` // ReportInterval specifies the interval duration for reporting status and logs of a running job. - Labels []string `yaml:"labels"` // Labels specify the labels of the runner. Labels are declared on each startup + File string `yaml:"file"` // File specifies the file path for the runner. + Capacity int `yaml:"capacity"` // Capacity specifies the capacity of the runner. + Envs map[string]string `yaml:"envs"` // Envs stores environment variables for the runner. + EnvFile string `yaml:"env_file"` // EnvFile specifies the path to the file containing environment variables for the runner. + Timeout time.Duration `yaml:"timeout"` // Timeout specifies the duration for runner timeout. + Insecure bool `yaml:"insecure"` // Insecure indicates whether the runner operates in an insecure mode. + FetchTimeout time.Duration `yaml:"fetch_timeout"` // FetchTimeout specifies the timeout duration for fetching resources. + FetchInterval time.Duration `yaml:"fetch_interval"` // FetchInterval specifies the interval duration for fetching resources. + Labels []string `yaml:"labels"` // Labels specifies the labels of the runner. Labels are declared on each startup } // Cache represents the configuration for caching. @@ -47,7 +45,6 @@ type Cache struct { type Container struct { Network string `yaml:"network"` // Network specifies the network for the container. NetworkMode string `yaml:"network_mode"` // Deprecated: use Network instead. Could be removed after Gitea 1.20 - EnableIPv6 bool `yaml:"enable_ipv6"` // EnableIPv6 indicates whether the network is created with IPv6 enabled. Privileged bool `yaml:"privileged"` // Privileged indicates whether the container runs in privileged mode. Options string `yaml:"options"` // Options specifies additional options for the container. WorkdirParent string `yaml:"workdir_parent"` // WorkdirParent specifies the parent directory for the container's working directory. @@ -70,16 +67,6 @@ type Config struct { Host Host `yaml:"host"` // Host represents the configuration for the host. } -// Tune the config settings accordingly to the Forgejo instance that will be used. -func (c *Config) Tune(instanceURL string) { - if instanceURL == "https://codeberg.org" { - if c.Runner.FetchInterval < 30*time.Second { - log.Info("The runner is configured to be used by a public instance, fetch interval is set to 30 seconds.") - c.Runner.FetchInterval = 30 * time.Second - } - } -} - // LoadDefault returns the default configuration. // If file is not empty, it will be used to load the configuration. func LoadDefault(file string) (*Config, error) { @@ -101,9 +88,6 @@ func LoadDefault(file string) (*Config, error) { if err != nil { return nil, fmt.Errorf("read env file %q: %w", cfg.Runner.EnvFile, err) } - if cfg.Runner.Envs == nil { - cfg.Runner.Envs = map[string]string{} - } for k, v := range envs { cfg.Runner.Envs[k] = v } @@ -145,9 +129,6 @@ func LoadDefault(file string) (*Config, error) { if cfg.Runner.FetchInterval <= 0 { cfg.Runner.FetchInterval = 2 * time.Second } - if cfg.Runner.ReportInterval <= 0 { - cfg.Runner.ReportInterval = time.Second - } // although `container.network_mode` will be deprecated, but we have to be compatible with it for now. if cfg.Container.NetworkMode != "" && cfg.Container.Network == "" { diff --git a/internal/pkg/config/config_test.go b/internal/pkg/config/config_test.go deleted file mode 100644 index d2ddf2f..0000000 --- a/internal/pkg/config/config_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2024 The Forgejo Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package config - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -func TestConfigTune(t *testing.T) { - c := &Config{ - Runner: Runner{}, - } - - t.Run("Public instance tuning", func(t *testing.T) { - c.Runner.FetchInterval = 60 * time.Second - c.Tune("https://codeberg.org") - assert.EqualValues(t, 60*time.Second, c.Runner.FetchInterval) - - c.Runner.FetchInterval = 2 * time.Second - c.Tune("https://codeberg.org") - assert.EqualValues(t, 30*time.Second, c.Runner.FetchInterval) - }) - - t.Run("Non-public instance tuning", func(t *testing.T) { - c.Runner.FetchInterval = 60 * time.Second - c.Tune("https://example.com") - assert.EqualValues(t, 60*time.Second, c.Runner.FetchInterval) - - c.Runner.FetchInterval = 2 * time.Second - c.Tune("https://codeberg.com") - assert.EqualValues(t, 2*time.Second, c.Runner.FetchInterval) - }) -} diff --git a/internal/pkg/envcheck/docker.go b/internal/pkg/envcheck/docker.go index f115bc7..0a634ad 100644 --- a/internal/pkg/envcheck/docker.go +++ b/internal/pkg/envcheck/docker.go @@ -27,7 +27,7 @@ func CheckIfDockerRunning(ctx context.Context, configDockerHost string) error { _, err = cli.Ping(ctx) if err != nil { - return fmt.Errorf("cannot ping the docker daemon. is it running? %w", err) + return fmt.Errorf("cannot ping the docker daemon, does it running? %w", err) } return nil diff --git a/internal/pkg/labels/labels.go b/internal/pkg/labels/labels.go index f448fdf..8c38b14 100644 --- a/internal/pkg/labels/labels.go +++ b/internal/pkg/labels/labels.go @@ -11,7 +11,6 @@ import ( const ( SchemeHost = "host" SchemeDocker = "docker" - SchemeLXC = "lxc" ) type Label struct { @@ -33,7 +32,7 @@ func Parse(str string) (*Label, error) { if len(splits) >= 3 { label.Arg = splits[2] } - if label.Schema != SchemeHost && label.Schema != SchemeDocker && label.Schema != SchemeLXC { + if label.Schema != SchemeHost && label.Schema != SchemeDocker { return nil, fmt.Errorf("unsupported schema: %s", label.Schema) } return label, nil @@ -56,11 +55,10 @@ func (l Labels) PickPlatform(runsOn []string) string { switch label.Schema { case SchemeDocker: // "//" will be ignored + // TODO maybe we should use 'ubuntu-18.04:docker:node:16-buster' instead platforms[label.Name] = strings.TrimPrefix(label.Arg, "//") case SchemeHost: platforms[label.Name] = "-self-hosted" - case SchemeLXC: - platforms[label.Name] = "lxc:" + strings.TrimPrefix(label.Arg, "//") default: // It should not happen, because Parse has checked it. continue @@ -82,7 +80,7 @@ func (l Labels) PickPlatform(runsOn []string) string { // So the runner receives a task with a label that the runner doesn't have, // it happens when the user have edited the label of the runner in the web UI. // TODO: it may be not correct, what if the runner is used as host mode only? - return "node:20-bullseye" + return "node:16-bullseye" } func (l Labels) Names() []string { diff --git a/internal/pkg/report/reporter.go b/internal/pkg/report/reporter.go index cee5062..7e9a2d5 100644 --- a/internal/pkg/report/reporter.go +++ b/internal/pkg/report/reporter.go @@ -12,8 +12,8 @@ import ( "time" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - "connectrpc.com/connect" retry "github.com/avast/retry-go/v4" + "github.com/bufbuild/connect-go" log "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" @@ -29,11 +29,10 @@ type Reporter struct { client client.Client clientM sync.Mutex - logOffset int - logRows []*runnerv1.LogRow - logReplacer *strings.Replacer - oldnew []string - reportInterval time.Duration + logOffset int + logRows []*runnerv1.LogRow + logReplacer *strings.Replacer + oldnew []string state *runnerv1.TaskState stateMu sync.RWMutex @@ -43,25 +42,21 @@ type Reporter struct { stopCommandEndToken string } -func NewReporter(ctx context.Context, cancel context.CancelFunc, client client.Client, task *runnerv1.Task, reportInterval time.Duration) *Reporter { +func NewReporter(ctx context.Context, cancel context.CancelFunc, client client.Client, task *runnerv1.Task) *Reporter { var oldnew []string if v := task.Context.Fields["token"].GetStringValue(); v != "" { oldnew = append(oldnew, v, "***") } - if v := task.Context.Fields["gitea_runtime_token"].GetStringValue(); v != "" { - oldnew = append(oldnew, v, "***") - } for _, v := range task.Secrets { oldnew = append(oldnew, v, "***") } rv := &Reporter{ - ctx: ctx, - cancel: cancel, - client: client, - oldnew: oldnew, - reportInterval: reportInterval, - logReplacer: strings.NewReplacer(oldnew...), + ctx: ctx, + cancel: cancel, + client: client, + oldnew: oldnew, + logReplacer: strings.NewReplacer(oldnew...), state: &runnerv1.TaskState{ Id: task.Id, }, @@ -116,9 +111,6 @@ func (r *Reporter) Fire(entry *log.Entry) error { for _, s := range r.state.Steps { if s.Result == runnerv1.Result_RESULT_UNSPECIFIED { s.Result = runnerv1.Result_RESULT_CANCELLED - if jobResult == runnerv1.Result_RESULT_SKIPPED { - s.Result = runnerv1.Result_RESULT_SKIPPED - } } } } @@ -182,7 +174,7 @@ func (r *Reporter) RunDaemon() { _ = r.ReportLog(false) _ = r.ReportState() - time.AfterFunc(r.reportInterval, r.RunDaemon) + time.AfterFunc(time.Second, r.RunDaemon) } func (r *Reporter) Logf(format string, a ...interface{}) { @@ -394,13 +386,12 @@ func (r *Reporter) handleCommand(originalContent, command, parameters, value str // Not implemented yet, so just return the original content. return &originalContent case "group": - // Rewriting into ##[] syntax which the frontend understands - content := "##[group]" + value - return &content + // Returning the original content, because I think the frontend + // will use it when rendering the output. + return &originalContent case "endgroup": // Ditto - content := "##[endgroup]" - return &content + return &originalContent case "stop-commands": r.stopCommandEndToken = value return nil @@ -427,7 +418,7 @@ func (r *Reporter) parseLogRow(entry *log.Entry) *runnerv1.LogRow { return &runnerv1.LogRow{ Time: timestamppb.New(entry.Time), - Content: strings.ToValidUTF8(content, "?"), + Content: content, } } diff --git a/internal/pkg/report/reporter_test.go b/internal/pkg/report/reporter_test.go index 524e972..d3d4c12 100644 --- a/internal/pkg/report/reporter_test.go +++ b/internal/pkg/report/reporter_test.go @@ -7,10 +7,9 @@ import ( "context" "strings" "testing" - "time" runnerv1 "code.gitea.io/actions-proto-go/runner/v1" - connect_go "connectrpc.com/connect" + connect_go "github.com/bufbuild/connect-go" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -97,8 +96,8 @@ func TestReporter_parseLogRow(t *testing.T) { "::endgroup::", }, []string{ - "##[group]", - "##[endgroup]", + "::group::", + "::endgroup::", }, }, { @@ -174,7 +173,7 @@ func TestReporter_Fire(t *testing.T) { require.NoError(t, err) reporter := NewReporter(ctx, cancel, client, &runnerv1.Task{ Context: taskCtx, - }, time.Second) + }) defer func() { assert.NoError(t, reporter.Close("")) }() diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 31da118..0000000 --- a/renovate.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["local>forgejo/renovate-config"], - "packageRules": [ - { - "description": "Disable nektos/act, it's replaced", - "matchDepNames": ["github.com/nektos/act"], - "enabled": false - } - ] -} diff --git a/scripts/systemd.md b/scripts/systemd.md deleted file mode 100644 index 089dd61..0000000 --- a/scripts/systemd.md +++ /dev/null @@ -1,67 +0,0 @@ -# Forgejo Runner with systemd User Services - -It is possible to use systemd's user services together with -[podman](https://podman.io/) to run `forgejo-runner` using a normal user -account without any privileges and automatically start on boot. - -This was last tested on Fedora 39 on 2024-02-19, but should work elsewhere as -well. - -Place the `forgejo-runner` binary in `/usr/local/bin/forgejo-runner` and make -sure it can be executed (`chmod +x /usr/local/bin/forgejo-runner`). - -Install and enable `podman` as a user service: - -```bash -$ sudo dnf -y install podman -``` - -You *may* need to reboot your system after installing `podman` as it -modifies some system configuration(s) that may need to be activated. Without -rebooting the system my runner errored out when trying to set firewall rules, a -reboot fixed it. - -Enable `podman` as a user service: - -``` -$ systemctl --user start podman.socket -$ systemctl --user enable podman.socket -``` - -Make sure processes remain after your user account logs out: - -```bash -$ loginctl enable-linger -``` - -Create the file `/etc/systemd/user/forgejo-runner.service` with the following -content: - -``` -[Unit] -Description=Forgejo Runner - -[Service] -Type=simple -ExecStart=/usr/local/bin/forgejo-runner daemon -Restart=on-failure - -[Install] -WantedBy=default.target -``` - -Now activate it as a user service: - -```bash -$ systemctl --user daemon-reload -$ systemctl --user start forgejo-runner -$ systemctl --user enable forgejo-runner -``` - -To see/follow the log of `forgejo-runner`: - -```bash -$ journalctl -f -t forgejo-runner -``` - -If you reboot your system, all should come back automatically.