diff --git a/.github/workflows/terraform-compatibility-matrix.yml b/.github/workflows/terraform-compatibility-matrix.yml new file mode 100644 index 0000000000..0f6b4418f3 --- /dev/null +++ b/.github/workflows/terraform-compatibility-matrix.yml @@ -0,0 +1,50 @@ +name: "HashiCorp Terraform Compatibility Matrix" +run-name: 'HashiCorp Terraform Compatibility Matrix ${{ inputs.atlas_cloud_env }}' + +on: + schedule: + - cron: "0 0 1-7 * 6" # runs first Saturday of the month at midnight UTC + workflow_dispatch: + inputs: + atlas_cloud_env: + description: 'Atlas cloud environment used, can be either `dev` or `qa`, empty for `dev`. Migration tests will always use `dev`' + type: string + required: false + test_group: + description: 'Test group to run, e.g. advanced_cluster, empty for all' + type: string + required: false + +jobs: + get-supported-versions: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - name: Get HashiCorp Terraform supported versions + shell: bash + id: get-terraform-supported-versions + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + output=$(./scripts/get-terraform-supported-versions.sh) + quoted_output=$(echo "${output}" | jq -c .) + echo "supported_versions=${quoted_output}" >> "${GITHUB_OUTPUT}" + outputs: + supported_versions: ${{ steps.get-terraform-supported-versions.outputs.supported_versions }} + + + run-test-supported-versions: + needs: ["get-supported-versions"] + if: ${{ !cancelled() }} + strategy: + max-parallel: 1 + fail-fast: false + matrix: + terraform_version: '${{ fromJSON(needs.get-supported-versions.outputs.supported_versions) }}' + name: terrafrom-compatibility-${{ matrix.terraform_version }}-${{ inputs.atlas_cloud_env || 'dev' }} + secrets: inherit + uses: ./.github/workflows/test-suite.yml + with: + terraform_matrix: '["${{ matrix.terraform_version }}"]' + atlas_cloud_env: ${{ inputs.atlas_cloud_env }} + diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 43bc8730f3..4ed3fadb2a 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -1,6 +1,6 @@ name: 'Test Suite' -# Runs acceptance and migrations tests with a set of terraform versions and provider versions (used for migration tests). This worflow is scheduled daily, but can also be run manually. +# Runs acceptance and migrations tests with a set of terraform versions and provider versions (used for migration tests). This worflow is scheduled daily except Saturdays, but can also be run manually. on: workflow_dispatch: inputs: @@ -10,9 +10,22 @@ on: provider_matrix: description: 'Previous MongoDB Atlas Provider version matrix for migration tests (JSON array)' default: '[""]' # "" for latest version + workflow_call: + inputs: + terraform_matrix: + description: 'Terraform version matrix (JSON array)' + type: string + provider_matrix: + description: 'Previous MongoDB Atlas Provider version matrix for migration tests (JSON array)' + type: string + default: '[""]' # "" for latest version + atlas_cloud_env: + description: 'Atlas cloud environment used, can be either `dev` or `qa`, empty for `dev`' + type: string + required: false schedule: - - cron: "0 0 * * *" # workflow runs every day at midnight UTC + - cron: "0 0 * * 0-5" # workflow runs every day at midnight UTC except on Saturdays concurrency: group: '${{ github.workflow }}' @@ -64,6 +77,7 @@ jobs: uses: ./.github/workflows/acceptance-tests.yml with: terraform_version: ${{ matrix.terraform_version }} + atlas_cloud_env: ${{ inputs.atlas_cloud_env }} clean-after: needs: [mig-tests, acc-tests] diff --git a/scripts/get-terraform-supported-versions.sh b/scripts/get-terraform-supported-versions.sh new file mode 100755 index 0000000000..0b47728365 --- /dev/null +++ b/scripts/get-terraform-supported-versions.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash + +# Copyright 2024 MongoDB Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set -euo pipefail +get_last_day_of_month() { + last_day_of_month=0 + case $1 in + 01|03|05|07|08|10|12) + last_day_of_month=31 ;; + 04|06|09|11) + last_day_of_month=30 ;; + 02) + # February: check if it's a leap year + if (( year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ) )); then + last_day_of_month=29 + else + last_day_of_month=28 + fi + ;; + esac + echo $last_day_of_month +} + + +add_end_support_date() { + new_json_list=$(echo "$1" | jq -c '.[]' | while IFS= read -r obj; do + input_date=$(echo "$obj" | jq -r '.published_at') + + # Extract the year, month, day, hour, minute, and second from the input date + year="${input_date:0:4}" + month="${input_date:5:2}" + hour="${input_date:11:2}" + minute="${input_date:14:2}" + second="${input_date:17:2}" + last_day_of_month=$(get_last_day_of_month "$month") + new_year=$((year + 2)) + + new_date="${new_year}-${month}-${last_day_of_month}T${hour}:${minute}:${second}Z" + + echo "$obj" | jq --arg new_date "${new_date}" '.end_support_date = $new_date' + done | jq -s '.') + + echo "$new_json_list" +} + +page=1 +api_version="2022-11-28" + +while true; do + response=$(curl -s \ + --request GET \ + --url "https://api.github.com/repos/hashicorp/terraform/releases?per_page=100&page=$page" \ + --header "Authorization: Bearer $GITHUB_TOKEN" \ + --header "X-GitHub-Api-Version: $api_version") + if [[ "$(printf '%s\n' "$response" | jq -e 'length == 0')" == "true" ]]; then + break + else + versions=$(echo "$response" | jq -r '.[] | {version: .tag_name, published_at: .published_at}') + filtered_versions_json=$(printf '%s\n' "${versions}" | jq -s '.') + updated_date_versions=$(add_end_support_date "$filtered_versions_json") + filtered_out_deprecated_versions=$(echo "$updated_date_versions" | jq 'map(select((.version | test("alpha|beta|rc"; "i") | not) and ((.end_support_date | fromdate) >= now))) | map(select(.version | endswith(".0")))') + + if [ -z ${json_array+x} ]; then + # If json_array is empty, assign filtered_versions directly + json_array=$(jq -n --argjson filtered_versions "${filtered_out_deprecated_versions}" '$filtered_versions') + else + # If json_array is not empty, append filtered_versions to it + json_array=$(echo "$json_array" | jq --argjson filtered_versions "${filtered_out_deprecated_versions}" '. + $filtered_versions') + fi + + ((page++)) + fi +done + +versions_array=$(printf '%s\n' "${json_array}" | jq -r '.[] | .version') + +formatted_output=$(echo "$versions_array" | awk 'BEGIN { ORS = "" } {gsub(/^v/,"",$1); gsub(/\.0$/,".x",$1); printf("%s\"%s\"", (NR==1?"":", "), $1)}' | sed 's/,"/," /g') + +echo "[$formatted_output]" | jq -c .