diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..6f0c4f881 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + commit-message: + prefix: "chore(ci)" + groups: + github-actions: + patterns: + - "*" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 51da5e535..000000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,154 +0,0 @@ -name: build -on: - push: - branches: - - master - tags: - - "v*.*.*" - pull_request: - branches: - - "*" -jobs: - build: - # You must use a Linux environment when using service containers or container jobs - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version-file: "go.mod" - - name: Check no diff - run: make check-no-diff - - name: Lint check - run: | - make lint - make helm-lint - - name: Vet check - run: make vet - - name: Install e2e dependencies - run: make install-playwright-ubuntu - - name: Install tofu for provider mirror setup - uses: opentofu/setup-opentofu@v1 - - name: Install terraform for provider mirror setup - uses: hashicorp/setup-terraform@v3 - with: - terraform_wrapper: false - - name: Add hosts to /etc/hosts - run: | - # API tests create webhooks on github.com, and github.com mandates - # that the webhook endpoint cannot be 'localhost', so we create a host - # entry to dupe github - sudo echo "127.0.0.1 otf.local" | sudo tee -a /etc/hosts - - name: API tests - run: make go-tfe-tests - env: - # go-tfe tests require a valid github oauth token be set with which - # to create a webhook on a github repo - OAUTH_CLIENT_GITHUB_TOKEN: ${{ secrets.GO_TFE_OAUTH_CLIENT_GITHUB_TOKEN }} - GITHUB_POLICY_SET_IDENTIFIER: leg100/go-tfe-webhooks - - name: Setup provider mirror for integration tests - run: ./hack/setup_mirror.sh - - name: Create kind cluster for integration tests - uses: helm/kind-action@v1.13.0 - with: - cluster_name: kind - - name: Tests - env: - OTF_TEST_KUBE: true - run: make test - - name: Archive browser traces - if: always() - uses: actions/upload-artifact@v4 - with: - name: e2e-browser-traces - path: internal/integration/traces - release-please: - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/master' - outputs: - release_created: ${{ steps.release-please.outputs.release_created }} - tag_name: ${{ steps.release-please.outputs.tag_name }} # e.g. v1.0.0 - version: ${{ steps.release-please.outputs.version }} # e.g. 1.0.0 - steps: - # Won't upgrade to v4 until they fix this bug: - # https://github.com/googleapis/release-please-action/issues/912 - - uses: google-github-actions/release-please-action@v3 - id: release-please - with: - release-type: go - command: manifest - release: - runs-on: ubuntu-latest - needs: [build, release-please] - if: needs.release-please.outputs.release_created - steps: - - uses: actions/checkout@v6 - with: - fetch-depth: 0 - - run: git fetch --force --tags - - uses: docker/login-action@v3 - with: - username: leg100 - password: ${{ secrets.DOCKERHUB_TOKEN }} - - uses: actions/setup-go@v6 - with: - go-version-file: "go.mod" - - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - uses: goreleaser/goreleaser-action@v6 - with: - args: release --clean --skip=sign,validate - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - charts: - # only upgrade charts for new releases - needs: [release-please, release] - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Bump version - run: | - # set app version on all charts - yq -i ".appVersion = \"${{ needs.release-please.outputs.version }}\"" ./charts/otfd/Chart.yaml - yq -i ".appVersion = \"${{ needs.release-please.outputs.version }}\"" ./charts/otf-agent/Chart.yaml - # bump patch in chart version - CHART=otfd make bump-chart-version - CHART=otf-agent make bump-chart-version - # re-generate README.md to reflect updated version - eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" - brew install norwoodj/tap/helm-docs - make helm-docs - - name: Lint check - run: | - make helm-lint - - name: Commit new helm chart versions - run: | - # stage changes and commit - git config --global user.email "chart-bumper@otf.ninja" - git config --global user.name "Chart bumper" - git add -A - git commit -m "chore: bump helm charts with app version ${{ needs.release-please.outputs.tag_name }}" - git push origin master - - name: Checkout charts repo - uses: actions/checkout@v6 - with: - path: otf-charts - token: ${{ secrets.OTF_CHARTS_TOKEN }} - repository: leg100/otf-charts - - name: Copy charts to charts repo - run: | - cp -R ./charts ./otf-charts/ - - name: Commit changes to otf-charts repo - run: | - # switch to checkout of otf-charts repo - cd ./otf-charts - # stage changes and commit - git config --global user.email "chart-bumper@otf.ninja" - git config --global user.name "Chart bumper" - git add -A - git commit -m "New otf version ${{ needs.release-please.outputs.tag_name }}" - git push origin master diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..4d27b9a30 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,176 @@ +name: Continuous Integration +on: + push: + branches: + - master + pull_request: + branches: + - master +permissions: + contents: read +# A new push to a PR cancels the PR's running CI. Master pushes get a group +# per commit, so each one runs to the end and saves caches. +concurrency: + group: ci-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true +# Caches are restored on every run and saved on master pushes only. The run ID +# in the Go cache keys makes each master push save a fresh build cache. +jobs: + lint: + runs-on: ubuntu-26.04 + timeout-minutes: 20 + steps: + - name: Checkout + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false + - name: Set up Go + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 + with: + go-version-file: "go.mod" + cache: false + - name: Restore Go cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + ~/.cache/staticcheck + key: go-lint-${{ runner.os }}-${{ hashFiles('go.sum') }}-${{ github.run_id }} + restore-keys: | + go-lint-${{ runner.os }}-${{ hashFiles('go.sum') }}- + go-lint-${{ runner.os }}- + - name: Check no diff + run: make check-no-diff + - name: Lint check + run: | + make lint + make helm-lint + - name: Vet check + run: make vet + - name: Save Go cache + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + ~/.cache/staticcheck + key: go-lint-${{ runner.os }}-${{ hashFiles('go.sum') }}-${{ github.run_id }} + test: + runs-on: ubuntu-26.04 + timeout-minutes: 60 + steps: + - name: Checkout + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false + - name: Set up Go + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 + with: + go-version-file: "go.mod" + cache: false + - name: Restore Go cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: go-test-${{ runner.os }}-${{ hashFiles('go.sum') }}-${{ github.run_id }} + restore-keys: | + go-test-${{ runner.os }}-${{ hashFiles('go.sum') }}- + go-test-${{ runner.os }}- + # The playwright version is pinned in go.mod. + - name: Restore playwright browsers + id: playwright-cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ hashFiles('go.sum') }} + - name: Install e2e dependencies + run: make install-playwright-ubuntu + - name: Save playwright browsers + if: github.event_name == 'push' && github.ref == 'refs/heads/master' && steps.playwright-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: ~/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ hashFiles('go.sum') }} + - name: Restore provider mirror + id: mirror-cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: mirror/registry.* + key: mirror-${{ hashFiles('mirror/providers.tf') }} + - name: Install tofu for provider mirror setup + if: steps.mirror-cache.outputs.cache-hit != 'true' + uses: opentofu/setup-opentofu@a1320f892987e89d278cc92dc5adc984fb93aca4 # v2.0.2 + - name: Install terraform for provider mirror setup + if: steps.mirror-cache.outputs.cache-hit != 'true' + uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2 + with: + terraform_wrapper: false + - name: Setup provider mirror for integration tests + if: steps.mirror-cache.outputs.cache-hit != 'true' + run: ./hack/setup_mirror.sh + - name: Save provider mirror + if: github.event_name == 'push' && github.ref == 'refs/heads/master' && steps.mirror-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: mirror/registry.* + key: mirror-${{ hashFiles('mirror/providers.tf') }} + - name: Create kind cluster for integration tests + uses: helm/kind-action@1544676c07bb3570fcb70166beaa07c4528fd4aa # v1.15.1 + with: + cluster_name: kind + - name: Tests + env: + OTF_TEST_KUBE: true + run: make test + - name: Save Go cache + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: go-test-${{ runner.os }}-${{ hashFiles('go.sum') }}-${{ github.run_id }} + api-tests: + runs-on: ubuntu-26.04 + timeout-minutes: 30 + steps: + - name: Checkout + uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0 + with: + persist-credentials: false + - name: Set up Go + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 + with: + go-version-file: "go.mod" + cache: false + # Also holds the go-tfe module that the API tests download. + - name: Restore Go cache + uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: go-api-${{ runner.os }}-${{ hashFiles('go.sum') }}-${{ github.run_id }} + restore-keys: | + go-api-${{ runner.os }}-${{ hashFiles('go.sum') }}- + go-api-${{ runner.os }}- + - name: Add hosts to /etc/hosts + run: | + # otfd is configured with hostname otf.local + echo "127.0.0.1 otf.local" | sudo tee -a /etc/hosts + - name: API tests + # VCS tests are skipped: they need a github oauth token to create a + # webhook on a real github repo. + run: make go-tfe-tests + - name: Save Go cache + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: go-api-${{ runner.os }}-${{ hashFiles('go.sum') }}-${{ github.run_id }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index c5ee745e3..000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: docs -on: - push: - branches: - - master -defaults: - run: - working-directory: ./docs -permissions: - contents: write -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Configure Git Credentials - run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - - uses: actions/setup-python@v5 - with: - python-version: 3.x - - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v4 - with: - key: mkdocs-material-${{ env.cache_id }} - path: .cache - restore-keys: | - mkdocs-material- - - run: pip install -r requirements.txt - - run: mkdocs gh-deploy --force diff --git a/hack/go-tfe-tests.bash b/hack/go-tfe-tests.bash index f43ab22eb..2145bca4a 100755 --- a/hack/go-tfe-tests.bash +++ b/hack/go-tfe-tests.bash @@ -122,17 +122,29 @@ echo "downloaded go-tfe module to $dest_dir" # some tests generate a tarball and save locally and need write perms chmod -R +w $dest_dir +compose_file=$PWD/docker-compose.testing.yml + cd $dest_dir +# capture failures rather than exit on them (set -e), so that otfd logs can be +# printed below +status=0 + +# the explicit package (.) selects package list mode, which prints only an +# `ok ` line on success, like `go test ./...` in the test job. That mode +# also caches results, but these tests depend on otfd, which the cache cannot +# see: -count=1 disables the cache. + # run beta tests unless user specifies tests (there is currently no way in this # script to specify individual *beta* tests to run) if [[ "$#" -eq 0 ]]; then - ENABLE_BETA=1 go test -v -run $allBetaTests -timeout 600s + ENABLE_BETA=1 go test . -count=1 -run $allBetaTests -timeout 600s || status=$? fi # run tests -go test -v -run ${@:-$all} -timeout 600s -skip $skipTests +go test . -count=1 -run ${@:-$all} -timeout 600s -skip $skipTests || status=$? # if tests fail then spit out otfd logs -if [[ $? -ne 0 ]]; then - docker compose logs otfd +if [[ $status -ne 0 ]]; then + docker compose -f $compose_file logs otfd fi +exit $status diff --git a/hack/setup_mirror.sh b/hack/setup_mirror.sh index ca067f868..b6acd7be1 100755 --- a/hack/setup_mirror.sh +++ b/hack/setup_mirror.sh @@ -1,5 +1,7 @@ +#!/usr/bin/env bash # Setup filesystem mirror for both terraform and tofu. This speeds up the # integration tests massively. +set -euo pipefail cd mirror/ terraform providers mirror . tofu providers mirror .