bazel: add terrafrom to //:check and //:generate

Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
Paul Meyer 2023-03-17 16:20:39 +01:00
parent 2693936906
commit 8d3fe6f477
7 changed files with 221 additions and 71 deletions

View File

@ -1,66 +0,0 @@
name: Terraform validation
on:
workflow_dispatch:
push:
branches:
- main
- "release/**"
paths:
- "**.tf"
- "**.lock.hcl"
- ".github/workflows/test-tf.yml"
pull_request:
paths:
- "**.tf"
- "**.lock.hcl"
- ".github/workflows/test-tf.yml"
jobs:
tfsec:
name: terraform
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
with:
ref: ${{ !github.event.pull_request.head.repo.fork && github.head_ref || '' }}
# No token available for forks, so we can't push changes
token: ${{ !github.event.pull_request.head.repo.fork && secrets.CI_COMMIT_PUSH_PR || '' }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 # tag=v2.0.3
- name: Terraform format and validate
shell: bash
run: |
dirs=$(find . -type f -name "*.tf" -exec dirname "{}" \; | sort -ud)
result=0
for dir in $dirs; do
echo "Checking $dir"
terraform -chdir="$dir" init || result=1
terraform -chdir="$dir" fmt -check=true -diff=true || result=1
terraform -chdir="$dir" validate -no-color || result=1
done
exit $result
- name: Check HCL lock files are up to date
id: hcl-lock
shell: bash
run: |
dirs=$( find . -type f -name "*.lock.hcl" -exec dirname "{}" \; | sort -ud)
for dir in $dirs; do
echo "Checking $dir"
terraform -chdir="$dir" init
terraform -chdir="$dir" providers lock -platform=linux_arm64 -platform=linux_amd64 -platform=darwin_arm64 -platform=darwin_amd64 -platform=windows_amd64
done
git diff --exit-code
- name: Push changes on renovate
if: failure() && (steps.hcl-lock.conclusion == 'failure') && startsWith(github.head_ref, 'renovate/')
shell: bash
run: |
git config --global user.name "edgelessci"
git config --global user.email "edgelessci@users.noreply.github.com"
git commit -am "deps: update HCL lock files"
git push

View File

@ -34,21 +34,62 @@ jobs:
shell: bash shell: bash
run: bazelisk run //:tidy run: bazelisk run //:tidy
- name: Check if tidy made modifications - name: Check if untidy
id: tidycheck id: untidy
shell: bash shell: bash
run: | run: |
diff=$(git diff) diff=$(git diff)
if [[ -z "$diff" ]]; then if [[ -z "$diff" ]]; then
echo "Everything is tidy" echo "Everything is tidy."
echo "untidy=false" >> "$GITHUB_OUTPUT"
exit 0 exit 0
fi fi
echo "Detected changes after tidy"
echo "untidy=true" >> "$GITHUB_OUTPUT"
- name: Run Bazel generate
shell: bash
run: bazelisk run //:generate
- name: Check if ungenerated
id: ungenerated
shell: bash
run: |
diff=$(git diff)
if [[ -z "$diff" ]]; then
echo "Everything is tidy."
echo "ungenerated=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "Detected changes after tidy"
echo "ungenerated=true" >> "$GITHUB_OUTPUT"
- name: Check if tidy or generate made modifications
id: modified
shell: bash
run: |
diff=$(git diff)
if [[ -z "$diff" ]]; then
echo "Everything is tidy and generated."
exit 0
fi
cat << EOF >> "${GITHUB_STEP_SUMMARY}" cat << EOF >> "${GITHUB_STEP_SUMMARY}"
\`\`\`diff \`\`\`diff
${diff} ${diff}
\`\`\` \`\`\`
EOF EOF
echo "::error::The repo is not tidy. Please run 'bazel run //:tidy' and commit the changes."
if [[ "${{ steps.untidy.outputs.untidy }}" == "true" ]] &&
[[ "${{ steps.ungenerated.outputs.ungenerated }}" == "true" ]]; then
suggestCmd="'bazel run //:generate' &&' bazel run //:tidy'"
elif [[ "${{ steps.untidy.outputs.untidy }}" == "true" ]]; then
suggestCmd="'bazel run //:tidy'"
elif [[ "${{ steps.ungenerated.outputs.ungenerated }}" == "true" ]]; then
suggestCmd="'bazel run //:generate'"
fi
echo "::error::The repo is not tidy. Please run ${suggestCmd} and commit the changes."
exit 1 exit 1
- name: Run Bazel check - name: Run Bazel check
@ -62,7 +103,7 @@ jobs:
- name: Push changes - name: Push changes
if: | if: |
failure() && failure() &&
(steps.tidycheck.conclusion == 'failure') && (steps.modified.conclusion == 'failure') &&
startsWith(github.head_ref, 'renovate/') && startsWith(github.head_ref, 'renovate/') &&
!github.event.pull_request.head.repo.fork !github.event.pull_request.head.repo.fork
shell: bash shell: bash

View File

@ -16,6 +16,11 @@ alias(
actual = "//bazel/ci:check", actual = "//bazel/ci:check",
) )
alias(
name = "generate",
actual = "//bazel/ci:generate",
)
alias( alias(
name = "devbuild", name = "devbuild",
actual = "//bazel/devbuild:devbuild", actual = "//bazel/devbuild:devbuild",

View File

@ -131,6 +131,40 @@ sh_template(
template = "tfsec.sh.in", template = "tfsec.sh.in",
) )
alias(
name = "com_github_hashicorp_terraform",
actual = select({
"@io_bazel_rules_go//go/platform:darwin_amd64": "@com_github_hashicorp_terraform_darwin_amd64//:terraform_bin",
"@io_bazel_rules_go//go/platform:darwin_arm64": "@com_github_hashicorp_terraform_darwin_arm64//:terraform_bin",
"@io_bazel_rules_go//go/platform:linux_amd64": "@com_github_hashicorp_terraform_linux_amd64//:terraform_bin",
"@io_bazel_rules_go//go/platform:linux_arm64": "@com_github_hashicorp_terraform_linux_arm64//:terraform_bin",
}),
)
sh_template(
name = "terraform_gen",
data = [
":com_github_hashicorp_terraform",
],
substitutions = {
"@@MODE@@": "generate",
"@@TERRAFORM@@": "$(rootpath :com_github_hashicorp_terraform)",
},
template = "tf.sh.in",
)
sh_template(
name = "terraform_check",
data = [
":com_github_hashicorp_terraform",
],
substitutions = {
"@@MODE@@": "check",
"@@TERRAFORM@@": "$(rootpath :com_github_hashicorp_terraform)",
},
template = "tf.sh.in",
)
multirun( multirun(
name = "tidy", name = "tidy",
commands = [ commands = [
@ -151,6 +185,7 @@ multirun(
commands = [ commands = [
":gazelle_check", ":gazelle_check",
":buildifier_check", ":buildifier_check",
":terraform_check",
] + select({ ] + select({
"@io_bazel_rules_go//go/platform:darwin_arm64": [ "@io_bazel_rules_go//go/platform:darwin_arm64": [
":shellcheck_noop_warning", ":shellcheck_noop_warning",
@ -164,3 +199,12 @@ multirun(
jobs = 1, # execute sequentially jobs = 1, # execute sequentially
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
multirun(
name = "generate",
commands = [
":terraform_gen",
],
jobs = 1, # execute sequentially
visibility = ["//visibility:public"],
)

82
bazel/ci/tf.sh.in Normal file
View File

@ -0,0 +1,82 @@
#!/usr/bin/env bash
lib=$(realpath @@BASE_LIB@@) || exit 1
terraform=$(realpath @@TERRAFORM@@) || exit 1
mode="@@MODE@@" || exit 1
# shellcheck source=../sh/lib.bash
if ! source "${lib}"; then
echo "Error: could not find import"
exit 1
fi
cd "${BUILD_WORKSPACE_DIRECTORY}" || exit 1
readarray -t <<< "$(
find "$(pwd)" -type f -name "*.tf" -exec dirname "{}" \; |
sort -ud
)"
terraformPaths=("${MAPFILE[@]}")
terraformModules=()
pathPrefix="${terraformPaths[0]}"
for ((i = 1; i < ${#terraformPaths[@]}; i++)); do
path="${terraformPaths[i]}"
if [[ ${path} == "${pathPrefix}"* ]]; then
continue
fi
terraformModules+=("${pathPrefix}")
pathPrefix="${path}"
done
excludeDirs=(
"build"
)
echo "The following Terraform modules are excluded and won't be tidied:"
for exclude in "${excludeDirs[@]}"; do
for i in "${!terraformModules[@]}"; do
if [[ ${terraformModules[i]} == "${BUILD_WORKSPACE_DIRECTORY}/${exclude}"* ]]; then
echo " ${terraformModules[i]}"
unset 'terraformModules[i]'
fi
done
done
case ${mode} in
"check")
echo "Checking validity and format of the following Terraform modules:"
for script in "${terraformModules[@]}"; do
echo " ${script}"
done
echo "This may take a minute..."
for module in "${terraformModules[@]}"; do
${terraform} -chdir="${module}" init > /dev/null
${terraform} -chdir="${module}" fmt -check -recursive > /dev/null
${terraform} -chdir="${module}" validate > /dev/null
rm -rf "${module}/.terraform"
done
;;
"generate")
echo "Formatting and generating lock files for the following Terraform modules:"
for script in "${terraformModules[@]}"; do
echo " ${script}"
done
echo "This may take 5-10 min..."
for module in "${terraformModules[@]}"; do
${terraform} -chdir="${module}" init > /dev/null
${terraform} -chdir="${module}" providers lock -platform=linux_arm64 > /dev/null
${terraform} -chdir="${module}" providers lock -platform=linux_amd64 > /dev/null
${terraform} -chdir="${module}" providers lock -platform=darwin_arm64 > /dev/null
${terraform} -chdir="${module}" providers lock -platform=darwin_amd64 > /dev/null
${terraform} -chdir="${module}" providers lock -platform=windows_amd64 > /dev/null
${terraform} -chdir="${module}" fmt -recursive > /dev/null
rm -rf "${module}/.terraform"
done
;;
*)
echo "Error: unknown mode \"${mode}\""
exit 1
;;
esac

View File

@ -0,0 +1,8 @@
genrule(
name = "terraform_bin",
srcs = ["terraform"],
outs = ["terraform_bin_out"],
cmd = "cp $< $@", # Copy the binary to the output directory.
executable = True,
visibility = ["//visibility:public"],
)

View File

@ -3,7 +3,9 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
def ci_deps(): def ci_deps():
"""Install CI dependencies"""
_shellcheck_deps() _shellcheck_deps()
_terraform_deps()
def _shellcheck_deps(): def _shellcheck_deps():
http_archive( http_archive(
@ -31,3 +33,37 @@ def _shellcheck_deps():
strip_prefix = "shellcheck-v0.9.0", strip_prefix = "shellcheck-v0.9.0",
build_file = "//bazel/toolchains:BUILD.shellcheck.bazel", build_file = "//bazel/toolchains:BUILD.shellcheck.bazel",
) )
def _terraform_deps():
http_archive(
name = "com_github_hashicorp_terraform_linux_amd64",
build_file = "//bazel/toolchains:BUILD.terraform.bazel",
urls = [
"https://releases.hashicorp.com/terraform/1.4.2/terraform_1.4.2_linux_amd64.zip",
],
sha256 = "9f3ca33d04f5335472829d1df7785115b60176d610ae6f1583343b0a2221a931",
)
http_archive(
name = "com_github_hashicorp_terraform_linux_arm64",
build_file = "//bazel/toolchains:BUILD.terraform.bazel",
urls = [
"https://releases.hashicorp.com/terraform/1.4.2/terraform_1.4.2_linux_arm64.zip",
],
sha256 = "39c182670c4e63e918e0a16080b1cc47bb16e158d7da96333d682d6a9cb8eb91",
)
http_archive(
name = "com_github_hashicorp_terraform_darwin_amd64",
build_file = "//bazel/toolchains:BUILD.terraform.bazel",
urls = [
"https://releases.hashicorp.com/terraform/1.4.2/terraform_1.4.2_darwin_amd64.zip",
],
sha256 = "c218a6c0ef6692b25af16995c8c7bdf6739e9638fef9235c6aced3cd84afaf66",
)
http_archive(
name = "com_github_hashicorp_terraform_darwin_arm64",
build_file = "//bazel/toolchains:BUILD.terraform.bazel",
urls = [
"https://releases.hashicorp.com/terraform/1.4.2/terraform_1.4.2_darwin_arm64.zip",
],
sha256 = "af8ff7576c8fc41496fdf97e9199b00d8d81729a6a0e821eaf4dfd08aa763540",
)