diff --git a/.github/workflows/base.yml b/.github/workflows/base.yml index f812f26d..1b29677d 100644 --- a/.github/workflows/base.yml +++ b/.github/workflows/base.yml @@ -4,6 +4,7 @@ on: paths: - Dockerfile.base - .github/workflows/base.yml + - goss* branches: - master - develop @@ -11,8 +12,114 @@ on: - cron: '0 22 * * *' jobs: + ubuntu_base_tests: + runs-on: ubuntu-latest + strategy: + matrix: + release: [jammy, focal, noble] + platform: [amd64, arm64] + fail-fast: false + steps: + - name: Copy Repo Files + uses: actions/checkout@master + - name: Get GitHub organization or user + run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Copy Dockerfile + run: cp Dockerfile.base Dockerfile.base.ubuntu-${{ matrix.release }}; sed -i.bak 's/FROM.*/FROM ubuntu:${{ matrix.release }}/' Dockerfile.base.ubuntu-${{ matrix.release }} + - name: Install Goss and dgoss + run: | + curl -fsSL https://goss.rocks/install | sh + export PATH=$PATH:/usr/local/bin + - name: Get current Git SHA + id: vars + run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: set testable image environment variable + id: testvars + run: echo "GH_RUNNER_IMAGE=ubuntu-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Build + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.base.ubuntu-${{ matrix.release }} + pull: true + push: false + load: true + tags: ${{ env.GH_RUNNER_IMAGE }} + platforms: linux/${{ matrix.platform }} + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Run goss tests + run: | + echo "os: ubuntu" >goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "oscodename: ${{ matrix.release }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "arch: ${{ matrix.platform }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_base.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + + debian_base_tests: + runs-on: ubuntu-latest + strategy: + matrix: + release: [bookworm, sid] + platform: [amd64, arm64] + fail-fast: false + steps: + - name: Copy Repo Files + uses: actions/checkout@master + - name: Get GitHub organization or user + run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Copy Dockerfile + run: cp Dockerfile.base Dockerfile.base.debian-${{ matrix.release }}; sed -i.bak 's/FROM.*/FROM debian:${{ matrix.release }}/' Dockerfile.base.debian-${{ matrix.release }} + - name: Install Goss and dgoss + run: | + curl -fsSL https://goss.rocks/install | sh + export PATH=$PATH:/usr/local/bin + - name: Get current Git SHA + id: vars + run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: set testable image environment variable + id: testvars + run: echo "GH_RUNNER_IMAGE=debian-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Build + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.base.debian-${{ matrix.release }} + pull: true + push: false + load: true + tags: ${{ env.GH_RUNNER_IMAGE }} + platforms: linux/${{ matrix.platform }} + cache-from: type=gha + cache-to: type=gha,mode=max + - name: Run goss tests + run: | + echo "os: debian" >goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "oscodename: ${{ matrix.release }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "arch: ${{ matrix.platform }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_base.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + + ubuntu_base_latest_deploy: runs-on: ubuntu-latest + needs: ubuntu_base_tests steps: - name: Copy Repo Files uses: actions/checkout@master @@ -41,6 +148,7 @@ jobs: ubuntu_base_deploy: runs-on: ubuntu-latest + needs: ubuntu_base_tests strategy: matrix: release: [jammy, focal, noble] @@ -75,6 +183,7 @@ jobs: debian_base_deploy: runs-on: ubuntu-latest + needs: debian_base_tests strategy: matrix: release: [bookworm, sid] diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a64f8051..0a5358db 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,8 +15,167 @@ permissions: packages: write jobs: + ubuntu_tests: + runs-on: ubuntu-latest + strategy: + matrix: + release: [jammy, focal, noble] + platform: [amd64, arm64] + fail-fast: false + steps: + - name: Copy Repo Files + uses: actions/checkout@master + - name: Get GitHub organization or user + run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Copy Dockerfile + run: cp Dockerfile Dockerfile.ubuntu-${{ matrix.release }}; sed -i.bak "s/FROM.*/FROM ${ORG}\/github-runner-base:ubuntu-${{ matrix.release }}/" Dockerfile.ubuntu-${{ matrix.release }} + - name: Install Goss and dgoss + run: | + curl -fsSL https://goss.rocks/install | sh + export PATH=$PATH:/usr/local/bin + - name: Get current Git SHA + id: vars + run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: set testable image environment variable + id: testvars + run: echo "GH_RUNNER_IMAGE=ubuntu-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Build + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.ubuntu-${{ matrix.release }} + pull: true + push: false + load: true + tags: ${{ env.GH_RUNNER_IMAGE }} + platforms: linux/${{ matrix.platform }} + cache-from: type=gha + cache-to: type=gha,mode=max + # Tests will run against the final `${GH_RUNNER_IMAGE}` laid on top of `base-${GH_RUNNER_IMAGE}` + - name: Run goss tests + run: | + echo "os: ubuntu" >goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "oscodename: ${{ matrix.release }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "arch: ${{ matrix.platform }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + # test the base + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_base.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with all defaults + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full_defaults.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with non-default values + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep \ + -e DEBUG_ONLY=true \ + -e RUNNER_NAME=huzzah \ + -e REPO_URL=https://github.com/myoung34/docker-github-actions-runner \ + -e RUN_AS_ROOT=true \ + -e RUNNER_NAME_PREFIX=asdf \ + -e ACCESS_TOKEN=1234 \ + -e APP_ID=5678 \ + -e APP_PRIVATE_KEY=2345 \ + -e APP_LOGIN=SOMETHING \ + -e RUNNER_SCOPE=org \ + -e ORG_NAME=myoung34 \ + -e ENTERPRISE_NAME=emyoung34 \ + -e LABELS=blue,green \ + -e RUNNER_TOKEN=3456 \ + -e RUNNER_WORKDIR=tmp/a \ + -e RUNNER_GROUP=wat \ + -e GITHUB_HOST=github.example.com \ + -e DISABLE_AUTOMATIC_DEREGISTRATION=true \ + -e EPHEMERAL=true \ + -e DISABLE_AUTO_UPDATE=true \ + ${GH_RUNNER_IMAGE} 10 + + debian_tests: + runs-on: ubuntu-latest + strategy: + matrix: + release: [bookworm, sid] + platform: [amd64, arm64] + fail-fast: false + steps: + - name: Copy Repo Files + uses: actions/checkout@master + - name: Get GitHub organization or user + run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Copy Dockerfile + run: cp Dockerfile Dockerfile.debian-${{ matrix.release }}; sed -i.bak "s/FROM.*/FROM ${ORG}\/github-runner-base:debian-${{ matrix.release }}/" Dockerfile.debian-${{ matrix.release }} + - name: Install Goss and dgoss + run: | + curl -fsSL https://goss.rocks/install | sh + export PATH=$PATH:/usr/local/bin + - name: Get current Git SHA + id: vars + run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: set testable image environment variable + id: testvars + run: echo "GH_RUNNER_IMAGE=debian-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Build + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.debian-${{ matrix.release }} + pull: true + push: false + load: true + tags: ${{ env.GH_RUNNER_IMAGE }} + platforms: linux/${{ matrix.platform }} + cache-from: type=gha + cache-to: type=gha,mode=max + # Tests will run against the final `${GH_RUNNER_IMAGE}` laid on top of `base-${GH_RUNNER_IMAGE}` + - name: Run goss tests + run: | + echo "os: debian" >goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "oscodename: ${{ matrix.release }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "arch: ${{ matrix.platform }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + # test the base + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_base.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with all defaults + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full_defaults.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with non-default values + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep \ + -e DEBUG_ONLY=true \ + -e RUNNER_NAME=huzzah \ + -e REPO_URL=https://github.com/myoung34/docker-github-actions-runner \ + -e RUN_AS_ROOT=true \ + -e RUNNER_NAME_PREFIX=asdf \ + -e ACCESS_TOKEN=1234 \ + -e APP_ID=5678 \ + -e APP_PRIVATE_KEY=2345 \ + -e APP_LOGIN=SOMETHING \ + -e RUNNER_SCOPE=org \ + -e ORG_NAME=myoung34 \ + -e ENTERPRISE_NAME=emyoung34 \ + -e LABELS=blue,green \ + -e RUNNER_TOKEN=3456 \ + -e RUNNER_WORKDIR=tmp/a \ + -e RUNNER_GROUP=wat \ + -e GITHUB_HOST=github.example.com \ + -e DISABLE_AUTOMATIC_DEREGISTRATION=true \ + -e EPHEMERAL=true \ + -e DISABLE_AUTO_UPDATE=true \ + ${GH_RUNNER_IMAGE} 10 + ubuntu_latest_deploy: runs-on: ubuntu-latest + needs: ubuntu_tests steps: - name: Copy Repo Files uses: actions/checkout@master @@ -53,6 +212,7 @@ jobs: ubuntu_deploy: runs-on: ubuntu-latest + needs: ubuntu_tests strategy: matrix: release: [jammy, focal, noble] @@ -93,6 +253,7 @@ jobs: debian_deploy: runs-on: ubuntu-latest + needs: debian_tests strategy: matrix: release: [bookworm, sid] diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dab947cb..c86bd402 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -5,7 +5,7 @@ name: "Trigger: Push action" jobs: tests: - name: Tests + name: Lint runs-on: ubuntu-latest steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 @@ -13,3 +13,169 @@ jobs: - uses: pre-commit/action@v3.0.1 - name: Run ShellCheck uses: ludeeus/action-shellcheck@master + + ubuntu_tests: + runs-on: ubuntu-latest + strategy: + matrix: + release: [jammy, focal, noble] + platform: [amd64, arm64] + fail-fast: false + steps: + - name: Copy Repo Files + uses: actions/checkout@master + - name: Get GitHub organization or user + run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Install Goss and dgoss + run: | + curl -fsSL https://goss.rocks/install | sh + export PATH=$PATH:/usr/local/bin + - name: Get current Git SHA + id: vars + run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: set testable image environment variable + id: testvars + run: echo "GH_RUNNER_IMAGE=ubuntu-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV + - name: Combine Dockerfile + run: | + cp Dockerfile.base Dockerfile.final.ubuntu-${{ matrix.release }}; + sed -i.bak 's/FROM.*/FROM ubuntu:${{ matrix.release }}/' Dockerfile.final.ubuntu-${{ matrix.release }} + + # Combine the dockerfiles + cp Dockerfile Dockerfile.ubuntu-${{ matrix.release }} + cat Dockerfile.ubuntu-${{ matrix.release }} | sed "s/^FROM.*//" >>Dockerfile.final.ubuntu-${{ matrix.release }} + + # Sanity check + grep FROM Dockerfile.final.ubuntu-${{ matrix.release }} + - name: Build final image + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.final.ubuntu-${{ matrix.release }} + pull: true + push: false + load: true + tags: ${{ env.GH_RUNNER_IMAGE }} + platforms: linux/${{ matrix.platform }} + cache-from: type=gha + cache-to: type=gha,mode=max + # Tests will run against the final `${GH_RUNNER_IMAGE}` laid on top of `base-${GH_RUNNER_IMAGE}` + - name: Run goss tests + run: | + echo "os: ubuntu" >goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "oscodename: ${{ matrix.release }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "arch: ${{ matrix.platform }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + # test the base + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_base.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with all defaults + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full_defaults.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with non-default values + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep \ + -e DEBUG_ONLY=true \ + -e RUNNER_NAME=huzzah \ + -e REPO_URL=https://github.com/myoung34/docker-github-actions-runner \ + -e RUN_AS_ROOT=true \ + -e RUNNER_NAME_PREFIX=asdf \ + -e ACCESS_TOKEN=1234 \ + -e APP_ID=5678 \ + -e APP_PRIVATE_KEY=2345 \ + -e APP_LOGIN=SOMETHING \ + -e RUNNER_SCOPE=org \ + -e ORG_NAME=myoung34 \ + -e ENTERPRISE_NAME=emyoung34 \ + -e LABELS=blue,green \ + -e RUNNER_TOKEN=3456 \ + -e RUNNER_WORKDIR=tmp/a \ + -e RUNNER_GROUP=wat \ + -e GITHUB_HOST=github.example.com \ + -e DISABLE_AUTOMATIC_DEREGISTRATION=true \ + -e EPHEMERAL=true \ + -e DISABLE_AUTO_UPDATE=true \ + ${GH_RUNNER_IMAGE} 10 + + debian_tests: + runs-on: ubuntu-latest + strategy: + matrix: + release: [bookworm, sid] + platform: [amd64, arm64] + fail-fast: false + steps: + - name: Copy Repo Files + uses: actions/checkout@master + - name: Get GitHub organization or user + run: echo 'ORG='$(echo $(dirname ${GITHUB_REPOSITORY}) | awk '{print tolower($0)}') >> $GITHUB_ENV + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Install Goss and dgoss + run: | + curl -fsSL https://goss.rocks/install | sh + export PATH=$PATH:/usr/local/bin + - name: Get current Git SHA + id: vars + run: echo "GIT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + - name: set testable image environment variable + id: testvars + run: echo "GH_RUNNER_IMAGE=debian-${{ matrix.release }}-${{ env.GIT_SHA }}-${{ matrix.platform }}" >> $GITHUB_ENV + - name: Combine Dockerfile + run: | + cp Dockerfile.base Dockerfile.final.debian-${{ matrix.release }} + sed -i.bak 's/FROM.*/FROM debian:${{ matrix.release }}/' Dockerfile.final.debian-${{ matrix.release }} + + # Combine the dockerfiles + cp Dockerfile Dockerfile.debian-${{ matrix.release }} + cat Dockerfile.debian-${{ matrix.release }} | sed "s/^FROM.*//" >>Dockerfile.final.debian-${{ matrix.release }} + + # Sanity check + grep FROM Dockerfile.final.debian-${{ matrix.release }} + - name: Build final image + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.final.debian-${{ matrix.release }} + pull: true + push: false + load: true + tags: ${{ env.GH_RUNNER_IMAGE }} + platforms: linux/${{ matrix.platform }} + cache-from: type=gha + cache-to: type=gha,mode=max + # Tests will run against the final `${GH_RUNNER_IMAGE}` laid on top of `base-${GH_RUNNER_IMAGE}` + - name: Run goss tests + run: | + echo "os: debian" >goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "oscodename: ${{ matrix.release }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + echo "arch: ${{ matrix.platform }}" >>goss_vars_${GH_RUNNER_IMAGE}.yaml + # test the base + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_base.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with all defaults + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full_defaults.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true ${GH_RUNNER_IMAGE} 10 + # test the final image but with non-default values + GOSS_VARS=goss_vars_${GH_RUNNER_IMAGE}.yaml GOSS_FILE=goss_full.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep \ + -e DEBUG_ONLY=true \ + -e RUNNER_NAME=huzzah \ + -e REPO_URL=https://github.com/myoung34/docker-github-actions-runner \ + -e RUN_AS_ROOT=true \ + -e RUNNER_NAME_PREFIX=asdf \ + -e ACCESS_TOKEN=1234 \ + -e APP_ID=5678 \ + -e APP_PRIVATE_KEY=2345 \ + -e APP_LOGIN=SOMETHING \ + -e RUNNER_SCOPE=org \ + -e ORG_NAME=myoung34 \ + -e ENTERPRISE_NAME=emyoung34 \ + -e LABELS=blue,green \ + -e RUNNER_TOKEN=3456 \ + -e RUNNER_WORKDIR=tmp/a \ + -e RUNNER_GROUP=wat \ + -e GITHUB_HOST=github.example.com \ + -e DISABLE_AUTOMATIC_DEREGISTRATION=true \ + -e EPHEMERAL=true \ + -e DISABLE_AUTO_UPDATE=true \ + ${GH_RUNNER_IMAGE} 10 diff --git a/.gitignore b/.gitignore index 751553b3..a0c51882 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.bak +.idea diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 82fad4bc..a3c103ee 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,6 +3,7 @@ repos: rev: v4.3.0 hooks: - id: check-yaml + exclude: goss_[a-z]*.yaml - id: end-of-file-fixer - id: trailing-whitespace - id: check-case-conflict diff --git a/README.md b/README.md index 62054e26..9a23e2cb 100644 --- a/README.md +++ b/README.md @@ -71,3 +71,51 @@ These containers are built via Github actions that [copy the dockerfile](https:/ | `DISABLE_AUTO_UPDATE` | Optional environment variable to [disable auto updates](https://github.blog/changelog/2022-02-01-github-actions-self-hosted-runners-can-now-disable-automatic-updates/). Auto updates are enabled by default to preserve past behavior. Any value is considered truthy and will disable them. | | `START_DOCKER_SERVICE` | Optional flag which automatically starts the docker service if set to `true`. Useful when using [sysbox](https://github.com/nestybox/sysbox). Defaults to `false`. | | `NO_DEFAULT_LABELS` | Optional environment variable to disable adding the default self-hosted, platform, and architecture labels to the runner. Any value is considered truthy and will disable them. | +| `DEBUG_ONLY` | Optional boolean to print debug output but not run any actual registration or runner commands. Used in CI and testing. Default: false | +| `DEBUG_OUTPUT` | Optional boolean to print additional debug output. Default: false | +| `UNSET_CONFIG_VARS` | Optional flag to unset all configuration environment variables after runner setup but before starting the runner. This prevents these variables from leaking into the workflow environment. Set to 'true' to enable. Defaults to 'false' for backward compatibility. | + +## Tests ## + +Tests are written in [goss](https://github.com/goss-org/goss/) for general assertions. +It's expected that all pull-requests have relevant assertions in order to be merged. + +Prereqs: Ensure that docker, goss and dgoss are set up +Note: while testing locally works, github actions will test all variations of operating systems and supported architectures. + +The test file expects the image to test as an environment variable `GH_RUNNER_IMAGE` to assist in CI + +To test: +``` +$ docker build -t my-base-test -f Dockerfile.base . +$ # Run the base test from Dockerfile.base on the current git HEAD +$ GH_RUNNER_IMAGE="my-base-test" GOSS_FILE=goss_base.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep -e RUNNER_NAME=test -e DEBUG_ONLY=true \ + ${GH_RUNNER_IMAGE} \ + 10 +$ # Use the base image in your final +$ sed -i.bak 's/^FROM.*/FROM my-base-test/g' Dockerfile +$ docker build -t my-full-test -f Dockerfile . +$ # Run the full test from Dockerfile.base on the current git HEAD +$ GH_RUNNER_IMAGE="my-full-test" GOSS_FILE=goss_full.yaml GOSS_SLEEP=1 dgoss run --entrypoint /usr/bin/sleep \ + -e DEBUG_ONLY=true \ + -e RUNNER_NAME=huzzah \ + -e REPO_URL=https://github.com/myoung34/docker-github-actions-runner \ + -e RUN_AS_ROOT=true \ + -e RUNNER_NAME_PREFIX=asdf \ + -e ACCESS_TOKEN=1234 \ + -e APP_ID=5678 \ + -e APP_PRIVATE_KEY=2345 \ + -e APP_LOGIN=SOMETHING \ + -e RUNNER_SCOPE=org \ + -e ORG_NAME=myoung34 \ + -e ENTERPRISE_NAME=emyoung34 \ + -e LABELS=blue,green \ + -e RUNNER_TOKEN=3456 \ + -e RUNNER_WORKDIR=tmp/a \ + -e RUNNER_GROUP=wat \ + -e GITHUB_HOST=github.example.com \ + -e DISABLE_AUTOMATIC_DEREGISTRATION=true \ + -e EPHEMERAL=true \ + -e DISABLE_AUTO_UPDATE=true \ + ${GH_RUNNER_IMAGE} 10 +``` diff --git a/entrypoint.sh b/entrypoint.sh index 5bdda1bb..cf0ed65c 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -14,6 +14,7 @@ export -n APP_PRIVATE_KEY trap_with_arg() { func="$1" ; shift for sig ; do + # shellcheck disable=SC2064 trap "$func $sig" "$sig" done } @@ -28,6 +29,8 @@ deregister_runner() { exit } +_DEBUG_ONLY=${DEBUG_ONLY:-false} +_DEBUG_OUTPUT=${DEBUG_OUTPUT:-false} _DISABLE_AUTOMATIC_DEREGISTRATION=${DISABLE_AUTOMATIC_DEREGISTRATION:-false} _RANDOM_RUNNER_SUFFIX=${RANDOM_RUNNER_SUFFIX:="true"} @@ -54,6 +57,8 @@ _RUNNER_GROUP=${RUNNER_GROUP:-Default} _GITHUB_HOST=${GITHUB_HOST:="github.com"} _RUN_AS_ROOT=${RUN_AS_ROOT:="true"} _START_DOCKER_SERVICE=${START_DOCKER_SERVICE:="false"} +_UNSET_CONFIG_VARS=${UNSET_CONFIG_VARS:="false"} +_CONFIGURED_ACTIONS_RUNNER_FILES_DIR=${CONFIGURED_ACTIONS_RUNNER_FILES_DIR:-""} # ensure backwards compatibility if [[ -z ${RUNNER_SCOPE} ]]; then @@ -148,37 +153,71 @@ configure_runner() { } +unset_config_vars() { + echo "Unsetting configuration environment variables" + unset RUN_AS_ROOT + unset RUNNER_NAME + unset RUNNER_NAME_PREFIX + unset RANDOM_RUNNER_SUFFIX + unset ACCESS_TOKEN + unset APP_ID + unset APP_PRIVATE_KEY + unset APP_LOGIN + unset RUNNER_SCOPE + unset ORG_NAME + unset ENTERPRISE_NAME + unset LABELS + unset REPO_URL + unset RUNNER_TOKEN + unset RUNNER_WORKDIR + unset RUNNER_GROUP + unset GITHUB_HOST + unset DISABLE_AUTOMATIC_DEREGISTRATION + unset CONFIGURED_ACTIONS_RUNNER_FILES_DIR + unset EPHEMERAL + unset DISABLE_AUTO_UPDATE + unset START_DOCKER_SERVICE + unset NO_DEFAULT_LABELS + unset UNSET_CONFIG_VARS +} # Opt into runner reusage because a value was given -if [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then +if [[ -n "${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then echo "Runner reusage is enabled" # directory exists, copy the data - if [[ -d "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then + if [[ -d "${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then echo "Copying previous data" - cp -p -r "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}/." "/actions-runner" + cp -p -r "${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}/." "/actions-runner" fi if [ -f "/actions-runner/.runner" ]; then echo "The runner has already been configured" else - configure_runner + + if [[ ${_DEBUG_ONLY} == "false" ]]; then + configure_runner + fi fi else echo "Runner reusage is disabled" - configure_runner + if [[ ${_DEBUG_ONLY} == "false" ]]; then + configure_runner + fi fi -if [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then - echo "Reusage is enabled. Storing data to ${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" +if [[ -n "${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]]; then + echo "Reusage is enabled. Storing data to ${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" # Quoting (even with double-quotes) the regexp brokes the copying - cp -p -r "/actions-runner/_diag" "/actions-runner/svc.sh" /actions-runner/.[^.]* "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" + cp -p -r "/actions-runner/_diag" "/actions-runner/svc.sh" /actions-runner/.[^.]* "${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" fi if [[ ${_DISABLE_AUTOMATIC_DEREGISTRATION} == "false" ]]; then - trap_with_arg deregister_runner SIGINT SIGQUIT SIGTERM INT TERM QUIT + if [[ ${_DEBUG_ONLY} == "false" ]]; then + trap_with_arg deregister_runner SIGINT SIGQUIT SIGTERM INT TERM QUIT + fi fi # Start docker service if needed (e.g. for docker-in-docker) @@ -186,27 +225,68 @@ if [[ ${_START_DOCKER_SERVICE} == "true" ]]; then echo "Starting docker service" _PREFIX="" [[ ${_RUN_AS_ROOT} != "true" ]] && _PREFIX="sudo" - ${_PREFIX} service docker start + + if [[ ${_DEBUG_ONLY} == "true" ]]; then + echo ${_PREFIX} service docker start + else + ${_PREFIX} service docker start + fi +fi + +# Unset configuration environment variables if the flag is set +if [[ ${_UNSET_CONFIG_VARS} == "true" ]]; then + unset_config_vars fi # Container's command (CMD) execution as runner user +if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then + echo "" + echo "Disable automatic registration: ${_DISABLE_AUTOMATIC_DEREGISTRATION}" + echo "Random runner suffix: ${_RANDOM_RUNNER_SUFFIX}" + echo "Runner name: ${_RUNNER_NAME}" + echo "Runner workdir: ${_RUNNER_WORKDIR}" + echo "Labels: ${_LABELS}" + echo "Runner Group: ${_RUNNER_GROUP}" + echo "Github Host: ${_GITHUB_HOST}" + echo "Run as root:${_RUN_AS_ROOT}" + echo "Start docker: ${_START_DOCKER_SERVICE}" +fi + if [[ ${_RUN_AS_ROOT} == "true" ]]; then if [[ $(id -u) -eq 0 ]]; then - "$@" + if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then + # shellcheck disable=SC2145 + echo "Running $@" + fi + if [[ ${_DEBUG_ONLY} == "false" ]]; then + "$@" + fi else echo "ERROR: RUN_AS_ROOT env var is set to true but the user has been overridden and is not running as root, but UID '$(id -u)'" exit 1 fi else if [[ $(id -u) -eq 0 ]]; then - [[ -n "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]] && chown -R runner "${CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" + [[ -n "${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" ]] && chown -R runner "${_CONFIGURED_ACTIONS_RUNNER_FILES_DIR}" chown -R runner "${_RUNNER_WORKDIR}" /actions-runner # The toolcache is not recursively chowned to avoid recursing over prepulated tooling in derived docker images chown runner /opt/hostedtoolcache/ - /usr/sbin/gosu runner "$@" + if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then + # shellcheck disable=SC2145 + echo "Running /usr/sbin/gosu runner $@" + fi + if [[ ${_DEBUG_ONLY} == "false" ]]; then + /usr/sbin/gosu runner "$@" + fi else - "$@" + if [[ ${_DEBUG_ONLY} == "true" ]] || [[ ${_DEBUG_OUTPUT} == "true" ]] ; then + # shellcheck disable=SC2145 + echo "Running $@" + fi + if [[ ${_DEBUG_ONLY} == "false" ]]; then + "$@" + fi fi fi diff --git a/goss_base.yaml b/goss_base.yaml new file mode 100644 index 00000000..ec70b938 --- /dev/null +++ b/goss_base.yaml @@ -0,0 +1,89 @@ +package: + curl: + installed: true + docker: + installed: false + docker-compose: + installed: false + git: + installed: true + git-lfs: + installed: false + jq: + installed: true + lsb_release: + installed: false + make: + installed: true + pwsh: + installed: false + python3: + installed: true + rsync: + installed: true + ssh: + installed: false + sudo: + installed: true + tar: + installed: true + unzip: + installed: true + wget: + installed: true + yq: + installed: false + # Ubuntu Focal is the only one currently that doesnt have an official upstream skopeo/buildah/podman + {{ if not (eq .Vars.oscodename "focal") }} + skopeo: + installed: true + buildah: + installed: true + podman: + installed: true + {{ end }} +file: + /usr/bin/gh: + exists: true + /usr/bin/nodejs: + exists: true + /usr/sbin/gosu: + exists: true + /usr/bin/dumb-init: + exists: true + /etc/init.d/docker: + exists: true + owner: root + group: root + filetype: file + contains: + - /^\s*# ulimit -Hn/ + /etc/sudoers: + exists: true + owner: root + group: root + filetype: file + contains: + - '/%sudo ALL=\(ALL\) NOPASSWD: ALL/' + - '/Defaults env_keep = "HTTP_PROXY HTTPS_PROXY NO_PROXY FTP_PROXY http_proxy https_proxy no_proxy ftp_proxy"/' + /etc/locale.gen: + exists: true + owner: root + group: root + filetype: file + contains: + - '/^en_US.UTF-8 UTF-8/' + +user: + runner: + exists: true + uid: 1001 + gid: 121 + groups: + - runner + - sudo + - docker +group: + runner: + exists: true + gid: 121 diff --git a/goss_full.yaml b/goss_full.yaml new file mode 100644 index 00000000..ade6f0fe --- /dev/null +++ b/goss_full.yaml @@ -0,0 +1,17 @@ +command: + /entrypoint.sh something: + exit-status: 0 + stdout: + - "Runner reusage is disabled" + - "" + - "Disable automatic registration: true" + - "Random runner suffix: true" + - "Runner name: huzzah" + - "Labels: blue,green" + - "Runner Group: wat" + - "Github Host: github.example.com" + - "Run as root:true" + - "Start docker: false" + - "Running something" + stderr: "" + timeout: 2000 diff --git a/goss_full_defaults.yaml b/goss_full_defaults.yaml new file mode 100644 index 00000000..ad3c87f4 --- /dev/null +++ b/goss_full_defaults.yaml @@ -0,0 +1,20 @@ +command: + /entrypoint.sh something: + exit-status: 0 + stdout: + - REPO_URL required for repo runners + - Runner reusage is disabled + - "" + - 'Disable automatic registration: false' + - 'Random runner suffix: true' + - 'Runner name: test' + - 'Runner workdir: /_work/test' + - 'Labels: default' + - 'Runner Group: Default' + - 'Github Host: github.com' + - Run as root:true + - 'Start docker: false' + - Running something + - "" + stderr: "" + timeout: 2000