From 257602697d3420f449e0caf6ec844c0c301a11ea Mon Sep 17 00:00:00 2001 From: Chris Munns Date: Fri, 17 Jul 2026 16:46:03 -0400 Subject: [PATCH] Add first-pass lint CI for pgcopydb-helpers and pgcopydb-templates Runs on any push or PR touching those two folders. Three parallel jobs: - shell: bash -n + shellcheck on all .sh files. Gates at warning severity; benign/unfixable codes (SC1090, SC2088, SC2034) are disabled in a repo-root .shellcheckrc, each with a note to tighten later. - cloudformation: cfn-lint on the AWS CloudFormation template. - terraform: fmt -check, init, validate, and tflint, matrixed over the aws and gcp template dirs. Also normalizes the two .tf files with terraform fmt (alignment only) so the fmt gate passes. All actions are pinned to full commit SHAs. --- .github/workflows/lint.yml | 81 +++++++++++++++++++ .shellcheckrc | 18 +++++ .../pgcopydb-migration-instance.tf | 8 +- .../pgcopydb-migration-instance.tf | 2 +- 4 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .shellcheckrc diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..a0a2796 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,81 @@ +name: lint + +# First-pass linting for the actively-developed migration paths. Runs on any +# commit or PR that touches these folders. Built to be extended — add jobs and +# tighten the existing gates over time. +on: + push: + paths: + - 'pgcopydb-helpers/**' + - 'pgcopydb-templates/**' + - '.github/workflows/lint.yml' + - '.shellcheckrc' + pull_request: + paths: + - 'pgcopydb-helpers/**' + - 'pgcopydb-templates/**' + - '.github/workflows/lint.yml' + - '.shellcheckrc' + +permissions: + contents: read + +jobs: + shell: + name: shell (shellcheck + bash -n) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: bash -n (syntax) + run: | + set -euo pipefail + find pgcopydb-helpers pgcopydb-templates -name '*.sh' -print0 \ + | xargs -0 -I{} bash -n "{}" + - name: shellcheck + # Gates at warning severity; benign/unfixable codes are disabled in + # the repo-root .shellcheckrc. Tighten (lower severity, drop disables) + # as the tree is cleaned. + run: | + set -euo pipefail + find pgcopydb-helpers pgcopydb-templates -name '*.sh' -print0 \ + | xargs -0 shellcheck --severity=warning + + cloudformation: + name: cloudformation (cfn-lint) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + with: + python-version: '3.12' + - name: install cfn-lint + run: pip install 'cfn-lint==1.52.1' + - name: cfn-lint + run: cfn-lint pgcopydb-templates/aws-cloudformation/*.yaml + + terraform: + name: terraform (fmt + validate + tflint) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + dir: + - pgcopydb-templates/aws-terraform + - pgcopydb-templates/gcp-terraform + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1 + with: + terraform_wrapper: false + - name: terraform fmt + run: terraform fmt -check -diff "${{ matrix.dir }}" + - name: terraform init + run: terraform -chdir="${{ matrix.dir }}" init -backend=false -input=false -no-color + - name: terraform validate + run: terraform -chdir="${{ matrix.dir }}" validate -no-color + - uses: terraform-linters/setup-tflint@6e1e0642c0289bd619021bf6b34e3c08ed1e005a # v6.3.0 + - name: tflint + working-directory: ${{ matrix.dir }} + run: | + tflint --init + tflint --no-color diff --git a/.shellcheckrc b/.shellcheckrc new file mode 100644 index 0000000..a6e0e66 --- /dev/null +++ b/.shellcheckrc @@ -0,0 +1,18 @@ +# Shared ShellCheck configuration for CI and local runs. +# CI gates at --severity=warning; the disables below silence findings that are +# either unfixable or benign across the whole tree. Revisit and tighten these +# as the scripts are cleaned up — that's the intended ratchet. + +# SC1090: scripts source ~/.env at runtime. The path is dynamic and cannot be +# resolved statically, so ShellCheck can never follow it. +disable=SC1090 + +# SC2088: every current hit is a tilde that is correct by construction — either +# literal text inside a user-facing message string, or a `bash -c` +# payload where the tilde reaches the inner shell unquoted and expands. +disable=SC2088 + +# SC2034: current hits are intentional positional field-skips in `read` and +# query result parsing. Re-enable after tightening those reads +# (e.g. `read -r name _ _ value`). +disable=SC2034 diff --git a/pgcopydb-templates/aws-terraform/pgcopydb-migration-instance.tf b/pgcopydb-templates/aws-terraform/pgcopydb-migration-instance.tf index 0bf36fe..c06d475 100644 --- a/pgcopydb-templates/aws-terraform/pgcopydb-migration-instance.tf +++ b/pgcopydb-templates/aws-terraform/pgcopydb-migration-instance.tf @@ -253,10 +253,10 @@ resource "aws_vpc_security_group_ingress_rule" "icmp_dest_unreachable" { # ============================================================================= resource "aws_instance" "pgcopydb" { - ami = data.aws_ssm_parameter.ubuntu_ami.value - instance_type = var.instance_type - key_name = var.key_pair_name != "" ? var.key_pair_name : null - iam_instance_profile = aws_iam_instance_profile.instance_profile.name + ami = data.aws_ssm_parameter.ubuntu_ami.value + instance_type = var.instance_type + key_name = var.key_pair_name != "" ? var.key_pair_name : null + iam_instance_profile = aws_iam_instance_profile.instance_profile.name subnet_id = var.subnet_id vpc_security_group_ids = [aws_security_group.pgcopydb.id] associate_public_ip_address = true diff --git a/pgcopydb-templates/gcp-terraform/pgcopydb-migration-instance.tf b/pgcopydb-templates/gcp-terraform/pgcopydb-migration-instance.tf index 2c84f0f..40276d1 100644 --- a/pgcopydb-templates/gcp-terraform/pgcopydb-migration-instance.tf +++ b/pgcopydb-templates/gcp-terraform/pgcopydb-migration-instance.tf @@ -261,7 +261,7 @@ resource "google_compute_instance" "pgcopydb_instance" { metadata = var.ssh_public_key != null ? { ssh-keys = "ubuntu:${var.ssh_public_key}" - } : { + } : { enable-oslogin = "TRUE" }