From d03e3a5ca095bd0eb0f69102a6ad0aaefbfe3ff6 Mon Sep 17 00:00:00 2001 From: Heather Lanigan Date: Thu, 14 Nov 2024 09:03:20 -0500 Subject: [PATCH] chore: optimize jobs for using PS6 runners PS6 runners are better suited to longer running jobs due to turn around time needed for refreshing a runner. Currently 15-30 minutes each. Small jobs will move back to using github runners to speed up the overall time for github actions to take. Tests requiring the build job, are moved to the same workflow to reduce the number of times we run the build job. Integration tests will be run on PS6 runners using a test parallelization of 10. --- .github/workflows/build.yml | 114 ----------------- .github/workflows/canary.yml | 2 +- .github/workflows/cla.yml | 6 +- .github/workflows/static-analysis.yaml | 83 ++++++++++++ .github/workflows/test_add_machine.yml | 126 ------------------- .github/workflows/test_integration.yml | 126 ++++++++++++++++--- .github/workflows/test_integration_jaas.yaml | 2 +- .github/workflows/unit_test.yaml | 44 ------- 8 files changed, 201 insertions(+), 302 deletions(-) delete mode 100644 .github/workflows/build.yml delete mode 100644 .github/workflows/test_add_machine.yml delete mode 100644 .github/workflows/unit_test.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index bf61e395..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,114 +0,0 @@ -# Terraform Provider testing workflow using different terraform versions -# and clouds. - -name: Build - -# This GitHub action runs your tests for each pull request. -on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review] -# paths-ignore: -# DON'T SET - these are "required" so they need to run on every PR - push: - branches: - - "main" - -# Testing only needs permissions to read the repository contents. -permissions: - contents: read - -jobs: - # Ensure project builds before running testing matrix - go-install: - name: install - runs-on: [self-hosted, jammy] - timeout-minutes: 5 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: true - - run: go mod tidy - - run: go install - - # Ensure the generated docs are up todate - generate: - runs-on: [self-hosted, jammy] - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: true - - uses: hashicorp/setup-terraform@v3 - with: - terraform_version: "1.9.*" - terraform_wrapper: false - - run: go generate ./... - - name: git diff - run: | - git diff --compact-summary --exit-code || \ - (echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1) - - # Ensure the go code is formatted properly - format: - runs-on: [self-hosted, jammy] - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: true - - run: gofmt -w -l -s . - - name: git diff - run: | - git diff --compact-summary --exit-code || \ - (echo; echo "Unexpected difference in directories after go fmt. Run 'gofmt -w -l -s .' command and commit."; exit 1) - - - # This runs golangci-lint against the codebase - lint: - name: golangci-lint - runs-on: [self-hosted, jammy] - steps: - - uses: actions/checkout@v4 - - name: Determine which tests to run - uses: dorny/paths-filter@v3 - id: filter - with: - filters: | - go: - - '**.go' - - 'go.mod' - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: false - - name: golangci-lint - uses: golangci/golangci-lint-action@v6 - with: - version: v1.54.0 - args: --print-issued-lines=true - - # This runs golangci-lint against the codebase - copyright-check: - name: copyright-check - runs-on: [self-hosted, jammy] - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: false - - run: | - OUT=$(find . -name '*.go' | sort | xargs grep -L -E '// (Copyright|Code generated)' || true) - LINES=$(echo "${OUT}" | wc -w) - if [ "$LINES" != 0 ]; then - echo "" - echo "$(red 'Found some issues:')" - echo -e '\nThe following files are missing copyright headers' - echo "${OUT}" - exit 1 - fi - diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index f5972a65..7afabb86 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -14,7 +14,7 @@ jobs: # Ensure project builds before running testing matrix build: name: Build - runs-on: [self-hosted, jammy] + runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 04301a0f..47ccc15d 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,16 +1,18 @@ -name: "CLA check" +name: "Static Analysis" on: [pull_request, workflow_dispatch] permissions: contents: read +# This task runs solo has it doesn't need to be run as often. jobs: cla-check: permissions: pull-requests: write # for canonical/has-signed-canonical-cla to create & update comments - runs-on: [self-hosted, jammy] + runs-on: ubuntu-latest steps: - name: Check if CLA signed uses: canonical/has-signed-canonical-cla@1.2.3 with: accept-existing-contributors: true + diff --git a/.github/workflows/static-analysis.yaml b/.github/workflows/static-analysis.yaml index eb2f3e82..35b52d67 100644 --- a/.github/workflows/static-analysis.yaml +++ b/.github/workflows/static-analysis.yaml @@ -8,10 +8,93 @@ on: permissions: contents: read +# These jobs are small independent tasks which are required, but do not +# gate any integration or unit tests. jobs: + # Ensure convention commits guidelines have been followed. conventional-commits: name: Check conventional commits runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: wagoid/commitlint-github-action@v6 + + # Ensure the generated docs are up-to-date + generate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache: true + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: "1.9.*" + terraform_wrapper: false + - run: go generate ./... + - name: git diff + run: | + git diff --compact-summary --exit-code || \ + (echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1) + + # Ensure the go code is formatted properly + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache: true + - run: gofmt -w -l -s . + - name: git diff + run: | + git diff --compact-summary --exit-code || \ + (echo; echo "Unexpected difference in directories after go fmt. Run 'gofmt -w -l -s .' command and commit."; exit 1) + + + # This runs golangci-lint against the codebase + lint: + name: golangci-lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Determine which tests to run + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + go: + - '**.go' + - 'go.mod' + - uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache: false + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.54.0 + args: --print-issued-lines=true + + # This runs copyright-check against the codebase + copyright-check: + name: copyright-check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache: false + - run: | + OUT=$(find . -name '*.go' | sort | xargs grep -L -E '// (Copyright|Code generated)' || true) + LINES=$(echo "${OUT}" | wc -w) + if [ "$LINES" != 0 ]; then + echo "" + echo "$(red 'Found some issues:')" + echo -e '\nThe following files are missing copyright headers' + echo "${OUT}" + exit 1 + fi diff --git a/.github/workflows/test_add_machine.yml b/.github/workflows/test_add_machine.yml deleted file mode 100644 index b6d06295..00000000 --- a/.github/workflows/test_add_machine.yml +++ /dev/null @@ -1,126 +0,0 @@ -# Terraform Provider testing workflow using different terraform versions -# on lxd. This action is specifically for testing manual provision. -# It sets up an external machine and adds it into the Juju model using -# terraform. -name: Manual machine provision - -on: - pull_request: - paths-ignore: - - "README.md" - - "project-docs/**" - - ".github/ISSUE_TEMPLATE/**" - - ".github/PULL_REQUEST_TEMPLATE.md" - push: - branches: - - "main" - paths-ignore: - - "README.md" - - "project-docs/**" - - ".github/ISSUE_TEMPLATE/**" - - ".github/PULL_REQUEST_TEMPLATE.md" - -# Testing only needs permissions to read the repository contents. -permissions: - contents: read - -jobs: - # Ensure project builds before running testing matrix - build: - name: Build - runs-on: [self-hosted, jammy] - timeout-minutes: 5 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: true - - run: go build -v . - - # Run acceptance tests in a matrix with Terraform CLI versions - add-machine-test: - name: Add Machine - needs: build - runs-on: [self-hosted, jammy] - env: - ACTIONS_ALLOW_IPV6: false - strategy: - fail-fast: false - matrix: - # Only on lxd - cloud: - - "lxd" - terraform: - - "1.9.*" - juju: - - "2.9/stable" - - "3/stable" - timeout-minutes: 60 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: true - # set up terraform - - uses: hashicorp/setup-terraform@v3 - with: - terraform_version: ${{ matrix.terraform }} - terraform_wrapper: false - # set up snap, lxd, tox, Juju, bootstrap a controller, etc. - - name: Setup operator environment - uses: charmed-kubernetes/actions-operator@main - with: - provider: ${{ matrix.cloud }} - juju-channel: ${{ matrix.juju }} - - name: "Set environment to configure provider" - # language=bash - run: | - CONTROLLER=$(juju whoami --format yaml | yq .controller) - - echo "JUJU_AGENT_VERSION=$(juju show-controller | yq .$CONTROLLER.details.agent-version |tr -d '"')" >> $GITHUB_ENV - echo "JUJU_CONTROLLER_ADDRESSES=$(juju show-controller | yq .$CONTROLLER.details.api-endpoints | yq -r '. | join(",")')" >> $GITHUB_ENV - echo "JUJU_USERNAME=$(juju show-controller | yq .$CONTROLLER.account.user)" >> $GITHUB_ENV - echo "JUJU_PASSWORD=$(cat ~/.local/share/juju/accounts.yaml | yq .controllers.$CONTROLLER.password)" >> $GITHUB_ENV - echo "JUJU_CA_CERT<> $GITHUB_ENV - juju show-controller | yq .$CONTROLLER.details.ca-cert >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV - - run: go mod download - - name: Create a new machine on lxd - run: | - /snap/bin/lxc launch ubuntu:22.04 mtest - echo "Waiting on the container to be up and ready" - while [[ -z $(lxc list --format=json | jq -r '.[] | select(.state.status == "Running") | .name' | grep mtest) ]]; do sleep 1; done - # Running status doesn't mean the network interface is up, so wait another 10 seconds - sleep 10 - echo "Container for test is ready" - - name: Final setup and test - env: - TF_ACC: "1" - TEST_CLOUD: ${{ matrix.cloud }} - run: | - # generate a new key pair and add it to the agent - ssh-keygen -t rsa -N "" -f ./test-add-machine - eval "$(ssh-agent -s)" - ssh-add ./test-add-machine - - # set the env variables - echo $(/snap/bin/lxc list mtest --format=json | jq -r '.[0].state.network.eth0.addresses[]') - export TEST_ADD_MACHINE_IP=$(/snap/bin/lxc list mtest --format=json | jq -r '.[0].state.network.eth0.addresses[] | select(.family == "inet").address') - export TEST_SSH_PUB_KEY_PATH=$(pwd)/test-add-machine.pub - export TEST_SSH_PRIV_KEY_PATH=$(pwd)/test-add-machine - echo "Testing with machine at $TEST_ADD_MACHINE_IP with keys $TEST_SSH_PUB_KEY_PATH and $TEST_SSH_PRIV_KEY_PATH" - - echo "Pushing the ssh public key at $TEST_SSH_PUB_KEY_PATH into the container" - /snap/bin/lxc file push $TEST_SSH_PUB_KEY_PATH mtest/home/ubuntu/.ssh/authorized_keys - - # to avoid the host key verification prompt - echo "adding the host fingerprint to known_hosts" - mkdir -p ~/.ssh - ssh-keyscan $TEST_ADD_MACHINE_IP >> ~/.ssh/known_hosts - - echo "Running the test" - cd ./internal/provider/ - go test ./... -timeout 30m -v -test.run TestAcc_ResourceMachine_AddMachine - timeout-minutes: 40 diff --git a/.github/workflows/test_integration.yml b/.github/workflows/test_integration.yml index 317397b2..1b4d833e 100644 --- a/.github/workflows/test_integration.yml +++ b/.github/workflows/test_integration.yml @@ -5,19 +5,12 @@ name: Integration tests # This GitHub action runs your tests for each pull request. on: pull_request: - paths-ignore: - - "README.md" - - "project-docs/**" - - ".github/ISSUE_TEMPLATE/**" - - ".github/PULL_REQUEST_TEMPLATE.md" + types: [opened, synchronize, reopened, ready_for_review] + # paths-ignore: + # DON'T SET - these are "required" so they need to run on every PR push: branches: - "main" - paths-ignore: - - "README.md" - - "project-docs/**" - - ".github/ISSUE_TEMPLATE/**" - - ".github/PULL_REQUEST_TEMPLATE.md" # Testing only needs permissions to read the repository contents. permissions: @@ -25,9 +18,11 @@ permissions: jobs: # Ensure project builds before running testing matrix + # This is a small job better suited to github runners, due to + # turn around time for self-hosted PS6 runners. build: name: Build - runs-on: [self-hosted, jammy] + runs-on: [ubuntu-latest] timeout-minutes: 5 steps: - uses: actions/checkout@v4 @@ -35,7 +30,23 @@ jobs: with: go-version-file: "go.mod" cache: true - - run: go build -v . + - run: go mod tidy + - run: go install + + # Run internal/juju unit tests + # This is a small job better suited to github runners, due to + # turn around time for self-hosted PS6 runners. + unittest: + name: Juju unit tests + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache: true + - run: make juju-unit-test # Run acceptance tests in a matrix with Terraform CLI versions test: @@ -45,7 +56,7 @@ jobs: strategy: fail-fast: false matrix: - terraform: ["1.7.*", "1.8.*", "1.9.*"] + terraform: ["1.9.*"] action-operator: - { lxd-channel: "5.21/stable", cloud: "lxd", cloud-channel: "5.21", juju: "2.9" } - { lxd-channel: "5.21/stable", cloud: "lxd", cloud-channel: "5.21", juju: "3" } @@ -106,5 +117,92 @@ jobs: - env: TF_ACC: "1" TEST_CLOUD: ${{ matrix.action-operator.cloud }} - run: go test -parallel 1 -timeout 40m -v -cover ./internal/provider/ + run: go test -parallel 10 -timeout 40m -v -cover ./internal/provider/ + timeout-minutes: 40 + + # Run acceptance tests in a matrix with Terraform CLI versions + add-machine-test: + name: Add Machine + needs: build + runs-on: [self-hosted, jammy] + env: + ACTIONS_ALLOW_IPV6: false + strategy: + fail-fast: false + matrix: + # Only on lxd + cloud: + - "lxd" + terraform: + - "1.9.*" + juju: + - "2.9/stable" + - "3/stable" + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache: true + # set up terraform + - uses: hashicorp/setup-terraform@v3 + with: + terraform_version: ${{ matrix.terraform }} + terraform_wrapper: false + # set up snap, lxd, tox, Juju, bootstrap a controller, etc. + - name: Setup operator environment + uses: charmed-kubernetes/actions-operator@main + with: + provider: ${{ matrix.cloud }} + juju-channel: ${{ matrix.juju }} + - name: "Set environment to configure provider" + # language=bash + run: | + CONTROLLER=$(juju whoami --format yaml | yq .controller) + + echo "JUJU_AGENT_VERSION=$(juju show-controller | yq .$CONTROLLER.details.agent-version |tr -d '"')" >> $GITHUB_ENV + echo "JUJU_CONTROLLER_ADDRESSES=$(juju show-controller | yq .$CONTROLLER.details.api-endpoints | yq -r '. | join(",")')" >> $GITHUB_ENV + echo "JUJU_USERNAME=$(juju show-controller | yq .$CONTROLLER.account.user)" >> $GITHUB_ENV + echo "JUJU_PASSWORD=$(cat ~/.local/share/juju/accounts.yaml | yq .controllers.$CONTROLLER.password)" >> $GITHUB_ENV + echo "JUJU_CA_CERT<> $GITHUB_ENV + juju show-controller | yq .$CONTROLLER.details.ca-cert >> $GITHUB_ENV + echo "EOF" >> $GITHUB_ENV + - run: go mod download + - name: Create a new machine on lxd + run: | + /snap/bin/lxc launch ubuntu:22.04 mtest + echo "Waiting on the container to be up and ready" + while [[ -z $(lxc list --format=json | jq -r '.[] | select(.state.status == "Running") | .name' | grep mtest) ]]; do sleep 1; done + # Running status doesn't mean the network interface is up, so wait another 10 seconds + sleep 10 + echo "Container for test is ready" + - name: Final setup and test + env: + TF_ACC: "1" + TEST_CLOUD: ${{ matrix.cloud }} + run: | + # generate a new key pair and add it to the agent + ssh-keygen -t rsa -N "" -f ./test-add-machine + eval "$(ssh-agent -s)" + ssh-add ./test-add-machine + + # set the env variables + echo $(/snap/bin/lxc list mtest --format=json | jq -r '.[0].state.network.eth0.addresses[]') + export TEST_ADD_MACHINE_IP=$(/snap/bin/lxc list mtest --format=json | jq -r '.[0].state.network.eth0.addresses[] | select(.family == "inet").address') + export TEST_SSH_PUB_KEY_PATH=$(pwd)/test-add-machine.pub + export TEST_SSH_PRIV_KEY_PATH=$(pwd)/test-add-machine + echo "Testing with machine at $TEST_ADD_MACHINE_IP with keys $TEST_SSH_PUB_KEY_PATH and $TEST_SSH_PRIV_KEY_PATH" + + echo "Pushing the ssh public key at $TEST_SSH_PUB_KEY_PATH into the container" + /snap/bin/lxc file push $TEST_SSH_PUB_KEY_PATH mtest/home/ubuntu/.ssh/authorized_keys + + # to avoid the host key verification prompt + echo "adding the host fingerprint to known_hosts" + mkdir -p ~/.ssh + ssh-keyscan $TEST_ADD_MACHINE_IP >> ~/.ssh/known_hosts + + echo "Running the test" + cd ./internal/provider/ + go test ./... -timeout 30m -v -test.run TestAcc_ResourceMachine_AddMachine timeout-minutes: 40 diff --git a/.github/workflows/test_integration_jaas.yaml b/.github/workflows/test_integration_jaas.yaml index 6209005c..876ce036 100644 --- a/.github/workflows/test_integration_jaas.yaml +++ b/.github/workflows/test_integration_jaas.yaml @@ -97,5 +97,5 @@ jobs: - env: TF_ACC: "1" TEST_CLOUD: "lxd" - run: go test -parallel 1 -timeout 40m -v -cover ./internal/provider/ + run: go test -parallel 10 -timeout 40m -v -cover ./internal/provider/ timeout-minutes: 40 diff --git a/.github/workflows/unit_test.yaml b/.github/workflows/unit_test.yaml deleted file mode 100644 index f5c7018e..00000000 --- a/.github/workflows/unit_test.yaml +++ /dev/null @@ -1,44 +0,0 @@ -# Terraform Provider testing workflow using different terraform versions -# and clouds. -name: Unit Tests - -# This GitHub action runs your tests for each pull request. -on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review] - # paths-ignore: - # DON'T SET - these are "required" so they need to run on every PR - push: - branches: - - "main" - -# Testing only needs permissions to read the repository contents. -permissions: - contents: read - -jobs: - # Ensure project builds before running unit tests - build: - name: Build - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: true - - run: go build -v . - - # Run internal/juju unit tests - test: - name: Juju unit tests - needs: build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: "go.mod" - cache: true - - run: make juju-unit-test