From 222d327f36ad48c692d63ed989740f3178bb130c Mon Sep 17 00:00:00 2001 From: Kaniska Date: Thu, 23 Jul 2026 13:35:19 +0000 Subject: [PATCH 1/4] Stress Test terraform PR change --- ...erraform-parallel-install-stress-test.yaml | 22 +++++ src/terraform/install.sh | 78 +++++++++++------ test/terraform/tflint_fallback_test.sh | 85 ++++++++++++------- 3 files changed, 132 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/terraform-parallel-install-stress-test.yaml diff --git a/.github/workflows/terraform-parallel-install-stress-test.yaml b/.github/workflows/terraform-parallel-install-stress-test.yaml new file mode 100644 index 000000000..e53c18001 --- /dev/null +++ b/.github/workflows/terraform-parallel-install-stress-test.yaml @@ -0,0 +1,22 @@ +name: "Stress test parallel installs - Terraform" +on: + pull_request: + paths: + - 'src/terraform/**' + workflow_dispatch: + +jobs: + test: + strategy: + matrix: + test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 ] + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Stress test 'terraform' install with default settings (pass ${{ matrix.test-pass }})" + run: devcontainer features test -f terraform --skip-scenarios . diff --git a/src/terraform/install.sh b/src/terraform/install.sh index 8bc79107c..7f15e8c3e 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -19,8 +19,8 @@ INSTALL_SENTINEL=${INSTALLSENTINEL:-false} INSTALL_TFSEC=${INSTALLTFSEC:-false} INSTALL_TERRAFORM_DOCS=${INSTALLTERRAFORMDOCS:-false} CUSTOM_DOWNLOAD_SERVER="${CUSTOMDOWNLOADSERVER:-""}" -# This is because ubuntu noble, ubuntu resolute and debian trixie don't support the old format of GPG keys and validation -NEW_GPG_CODENAMES="trixie noble resolute" +# This is because ubuntu noble and debian trixie don't support the old format of GPG keys and validation +NEW_GPG_CODENAMES="trixie noble" TERRAFORM_SHA256="${TERRAFORM_SHA256:-"automatic"}" TFLINT_SHA256="${TFLINT_SHA256:-"automatic"}" @@ -52,7 +52,7 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi -# Detect Ubuntu Noble, Ubuntu Resolute or Debian Trixie and use new repo setup, else use legacy GPG logic +# Detect Ubuntu Noble or Debian Trixie and use new repo setup, else use legacy GPG logic IS_GPG_NEW=0 . /etc/os-release if [[ "${NEW_GPG_CODENAMES}" == *"${VERSION_CODENAME}"* ]]; then @@ -249,7 +249,7 @@ find_sentinel_version_from_url() { if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then local prefix='sentinel_' local regex="${prefix}\d.\d{2}.\d(?:-\w*)?" - local version_list="$(wget -q $2 -O - | grep -oP ${regex} | sed "s/^${prefix}//" | sort -rV)" + local version_list="$(wget -q $2 -O - | grep -oP ${regex} | tr -d ${prefix} | sort -rV)" if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" else @@ -460,6 +460,23 @@ install_tflint() { curl -sSL -o /tmp/tf-downloads/${TFLINT_FILENAME} https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/${TFLINT_FILENAME} } +verify_tflint_attestations() { + local checksums=$1 + local checksums_sha256=$(sha256sum "$checksums" | cut -d " " -f 1) + + check_packages jq + + curl -L -f "https://api.github.com/repos/terraform-linters/tflint/attestations/sha256:${checksums_sha256}" > attestation.json + curl_exit_code=$? + if [ $curl_exit_code -ne 0 ]; then + echo "(*) Failed to fetch GitHub Attestations for tflint checksums" + return 1 + fi + + jq ".attestations[].bundle" attestation.json > bundle.jsonl + gh at verify "$checksums" -R terraform-linters/tflint -b bundle.jsonl +} + if [ "${TFLINT_VERSION}" != "none" ]; then echo "Downloading tflint..." TFLINT_FILENAME="tflint_linux_${architecture}.zip" @@ -475,31 +492,44 @@ if [ "${TFLINT_VERSION}" != "none" ]; then else curl -sSL -o tflint_checksums.txt https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt + # Attempt GitHub Attestation verification (0.51.1+) set +e - curl -sSL -o checksums.txt.keyless.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.keyless.sig + verify_tflint_attestations tflint_checksums.txt + verify_result=$? set -e - # Check that checksums.txt.keyless.sig exists and is not empty - if [ -s checksums.txt.keyless.sig ]; then - # Validate checksums with cosign - curl -sSL -o checksums.txt.pem https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.pem - ensure_cosign - cosign verify-blob \ - --certificate=/tmp/tf-downloads/checksums.txt.pem \ - --signature=/tmp/tf-downloads/checksums.txt.keyless.sig \ - --certificate-identity-regexp="^https://github.com/terraform-linters/tflint" \ - --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ - /tmp/tf-downloads/tflint_checksums.txt - # Ensure that checksums.txt has $TFLINT_FILENAME - grep ${TFLINT_FILENAME} /tmp/tf-downloads/tflint_checksums.txt - # Validate downloaded file + if [ $verify_result -eq 0 ]; then sha256sum --ignore-missing -c tflint_checksums.txt + echo "(*) tflint_checksums.txt verified successfully using GitHub Attestation." else - # Fallback to older, GPG-based verification (pre-0.47.0 of tflint) - curl -sSL -o tflint_checksums.txt.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.sig - curl -sSL -o tflint_key "${TFLINT_GPG_KEY_URI}" - gpg -q --import tflint_key - gpg --verify tflint_checksums.txt.sig tflint_checksums.txt + # Fallback to cosign verification + echo "(*) GitHub Attestation verification failed or not supported for this version, falling back to Cosign verification..." + set +e + curl -sSL -o checksums.txt.keyless.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.keyless.sig + set -e + + # Check that checksums.txt.keyless.sig exists and is not empty + if [ -s checksums.txt.keyless.sig ]; then + # Validate checksums with cosign + curl -sSL -o checksums.txt.pem https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.pem + ensure_cosign + cosign verify-blob \ + --certificate=/tmp/tf-downloads/checksums.txt.pem \ + --signature=/tmp/tf-downloads/checksums.txt.keyless.sig \ + --certificate-identity-regexp="^https://github.com/terraform-linters/tflint" \ + --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ + /tmp/tf-downloads/tflint_checksums.txt + # Ensure that checksums.txt has $TFLINT_FILENAME + grep ${TFLINT_FILENAME} /tmp/tf-downloads/tflint_checksums.txt + # Validate downloaded file + sha256sum --ignore-missing -c tflint_checksums.txt + else + # Fallback to older, GPG-based verification (pre-0.47.0 of tflint) + curl -sSL -o tflint_checksums.txt.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.sig + curl -sSL -o tflint_key "${TFLINT_GPG_KEY_URI}" + gpg -q --import tflint_key + gpg --verify tflint_checksums.txt.sig tflint_checksums.txt + fi fi fi fi diff --git a/test/terraform/tflint_fallback_test.sh b/test/terraform/tflint_fallback_test.sh index 5619ff4fb..33b75f3b0 100644 --- a/test/terraform/tflint_fallback_test.sh +++ b/test/terraform/tflint_fallback_test.sh @@ -22,7 +22,6 @@ keyserver hkps://keys.openpgp.org keyserver hkps://keyserver.pgp.com" check "tflint version as installed by feature" tflint --version -check "cosign version as installed by feature" cosign version architecture="$(uname -m)" case ${architecture} in @@ -221,14 +220,31 @@ install_tflint() { curl -sSL -o /tmp/tf-downloads/${TFLINT_FILENAME} https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/${TFLINT_FILENAME} } +verify_tflint_attestations() { + local checksums=$1 + local checksums_sha256=$(sha256sum "$checksums" | cut -d " " -f 1) -try_install_dummy_tflint_cosign_version() { + check_packages jq + + curl -L -f "https://api.github.com/repos/terraform-linters/tflint/attestations/sha256:${checksums_sha256}" > attestation.json + curl_exit_code=$? + if [ $curl_exit_code -ne 0 ]; then + echo "(*) Failed to fetch GitHub Attestations for tflint checksums" + return 1 + fi + + jq ".attestations[].bundle" attestation.json > bundle.jsonl + gh at verify "$checksums" -R terraform-linters/tflint -b bundle.jsonl +} + + +try_install_dummy_tflint_version() { mode=$1 tflint_url='https://github.com/terraform-linters/tflint' mkdir -p /tmp/tf-downloads cd /tmp/tf-downloads echo -e "\nTrying to install dummy tflint version..." - TFLINT_VERSION="0.50.XYZ" + TFLINT_VERSION="0.60.XYZ" echo "Downloading tflint...v${TFLINT_VERSION}" TFLINT_FILENAME="tflint_linux_${architecture}.zip" install_tflint "$TFLINT_VERSION" @@ -237,37 +253,50 @@ try_install_dummy_tflint_cosign_version() { fi if [ "${TFLINT_SHA256}" != "dev-mode" ]; then - if [ "${TFLINT_SHA256}" != "automatic" ]; then + if [ "${TFLINT_SHA256}" != "automatic" ]; then echo "${TFLINT_SHA256} *${TFLINT_FILENAME}" > tflint_checksums.txt sha256sum --ignore-missing -c tflint_checksums.txt else curl -sSL -o tflint_checksums.txt https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt + # Attempt GitHub Attestation verification (0.51.1+) set +e - curl -sSL -o checksums.txt.keyless.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.keyless.sig + verify_tflint_attestations tflint_checksums.txt + verify_result=$? set -e - - # Check that checksums.txt.keyless.sig exists and is not empty - if [ -s checksums.txt.keyless.sig ]; then - # Validate checksums with cosign - curl -sSL -o checksums.txt.pem https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.pem - ensure_cosign $mode - cosign verify-blob \ - --certificate=/tmp/tf-downloads/checksums.txt.pem \ - --signature=/tmp/tf-downloads/checksums.txt.keyless.sig \ - --certificate-identity-regexp="^https://github.com/terraform-linters/tflint" \ - --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ - /tmp/tf-downloads/tflint_checksums.txt - # Ensure that checksums.txt has $TFLINT_FILENAME - grep ${TFLINT_FILENAME} /tmp/tf-downloads/tflint_checksums.txt - # Validate downloaded file + + if [ $verify_result -eq 0 ]; then sha256sum --ignore-missing -c tflint_checksums.txt + echo "(*) tflint_checksums.txt verified successfully using GitHub Attestation." else - # Fallback to older, GPG-based verification (pre-0.47.0 of tflint) - curl -sSL -o tflint_checksums.txt.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.sig - curl -sSL -o tflint_key "${TFLINT_GPG_KEY_URI}" - gpg -q --import tflint_key - gpg --verify tflint_checksums.txt.sig tflint_checksums.txt + # Fallback to cosign verification + echo "(*) GitHub Attestation verification failed or not supported for this version, falling back to Cosign verification..." + set +e + curl -sSL -o checksums.txt.keyless.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.keyless.sig + set -e + + # Check that checksums.txt.keyless.sig exists and is not empty + if [ -s checksums.txt.keyless.sig ]; then + # Validate checksums with cosign + curl -sSL -o checksums.txt.pem https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.pem + ensure_cosign $mode + cosign verify-blob \ + --certificate=/tmp/tf-downloads/checksums.txt.pem \ + --signature=/tmp/tf-downloads/checksums.txt.keyless.sig \ + --certificate-identity-regexp="^https://github.com/terraform-linters/tflint" \ + --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ + /tmp/tf-downloads/tflint_checksums.txt + # Ensure that checksums.txt has $TFLINT_FILENAME + grep ${TFLINT_FILENAME} /tmp/tf-downloads/tflint_checksums.txt + # Validate downloaded file + sha256sum --ignore-missing -c tflint_checksums.txt + else + # Fallback to older, GPG-based verification (pre-0.47.0 of tflint) + curl -sSL -o tflint_checksums.txt.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.sig + curl -sSL -o tflint_key "${TFLINT_GPG_KEY_URI}" + gpg -q --import tflint_key + gpg --verify tflint_checksums.txt.sig tflint_checksums.txt + fi fi fi fi @@ -276,12 +305,10 @@ try_install_dummy_tflint_cosign_version() { sudo mv -f tflint /usr/local/bin/ } -try_install_dummy_tflint_cosign_version "mode1" +try_install_dummy_tflint_version "mode1" check "tflint version as installed when mode=1" tflint --version -check "cosign version as installed when mode=1" cosign version -try_install_dummy_tflint_cosign_version "mode2" +try_install_dummy_tflint_version "mode2" check "tflint version as installed when mode=2" tflint --version -check "cosign version as installed when mode=2" cosign version \ No newline at end of file From c4a3e0dc70853105d518fe89cdf9cf2e7a6b4367 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Thu, 23 Jul 2026 14:48:11 +0000 Subject: [PATCH 2/4] Update to 200 parallel instances to test --- .github/workflows/terraform-parallel-install-stress-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform-parallel-install-stress-test.yaml b/.github/workflows/terraform-parallel-install-stress-test.yaml index e53c18001..bf6f6afd1 100644 --- a/.github/workflows/terraform-parallel-install-stress-test.yaml +++ b/.github/workflows/terraform-parallel-install-stress-test.yaml @@ -9,7 +9,7 @@ jobs: test: strategy: matrix: - test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100 ] + test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200 ] fail-fast: false runs-on: ubuntu-latest steps: From ff02edcad14ab8104a19f9a8dd465693f64ec2c9 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Thu, 23 Jul 2026 14:59:57 +0000 Subject: [PATCH 3/4] Update to 300 parallel instances to test --- .github/workflows/terraform-parallel-install-stress-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform-parallel-install-stress-test.yaml b/.github/workflows/terraform-parallel-install-stress-test.yaml index bf6f6afd1..4d46dbaac 100644 --- a/.github/workflows/terraform-parallel-install-stress-test.yaml +++ b/.github/workflows/terraform-parallel-install-stress-test.yaml @@ -9,7 +9,7 @@ jobs: test: strategy: matrix: - test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200 ] + test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300 ] fail-fast: false runs-on: ubuntu-latest steps: From b888cdb5b9fc7d52d6b39a40d35cc2a285762aa9 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Thu, 23 Jul 2026 15:50:19 +0000 Subject: [PATCH 4/4] Update to 250 parallel instances to test --- .github/workflows/terraform-parallel-install-stress-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/terraform-parallel-install-stress-test.yaml b/.github/workflows/terraform-parallel-install-stress-test.yaml index 4d46dbaac..153b42e15 100644 --- a/.github/workflows/terraform-parallel-install-stress-test.yaml +++ b/.github/workflows/terraform-parallel-install-stress-test.yaml @@ -9,7 +9,7 @@ jobs: test: strategy: matrix: - test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300 ] + test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250 ] fail-fast: false runs-on: ubuntu-latest steps: