Skip to content

Commit f326080

Browse files
actuarysailorpre-commit-ci[bot]Copilot
authored
feat: Added Docker based pre-commit-hooks (#1)
* Add Docker-based pre-commit hooks implementation - Add Docker-based versions of terraform hooks (*_docker variants) - Create Dockerfile.tools for individual tool execution - Add GitHub Actions workflow for automated Docker image building - Include comprehensive documentation and examples - Maintain backward compatibility with existing script-based hooks * Fix Docker workflow test step and add latest tag for feature branch - Update test step to use dynamic tag instead of hardcoded :latest - Add :latest tag for feat/use-docker-pre-commit branch to match hook expectations * Fix corrupted .pre-commit-hooks.yaml and properly add Docker hooks - Restore clean hooks file structure - Add Docker-based hook variants at the end of file - Ensure proper YAML formatting and syntax * Fix docker_image language syntax: use image name in entry field * Fix all Docker hooks syntax and add pass_filenames for validate * Fix tflint Docker hook to use --chdir argument * Add pass_filenames false to terraform_docs_docker * Fix terraform_docs_docker argument order * Add pass_filenames false to all remaining Docker hooks * Clean up temporary files and add Docker hooks documentation - Remove temporary documentation files and unused wrapper scripts - Update README.md with comprehensive Docker hooks documentation - Update example config to use stable release version - Maintain backward compatibility - all original hooks unchanged * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * chore: Pre-commit fixes * Update README.md Co-authored-by: Copilot <[email protected]> * Update .pre-commit-hooks.yaml Co-authored-by: Copilot <[email protected]> * chore: Undo copilot recommendation * fix: Example file should point to upstream repo * chore(ci): Maintain workflows * fix: Pre-commit security issues * fix: One more pre-commit security risk * fix: Pre-commit security issue * fix: Pre-commit security issue * fix: One more try * fix: Final security issue * chore: Enhanced testing * fix: Hadolint error * fix: Consistent build conditions for all images * fix: Hadolint? * chore: Testing load switch * chore: Test expanded matrix method * fix: Remove dependency on other docker image * fix: Added the hadolint hint * fix: Build artifacts * chore: Linting * fix: Build artifacting * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix: Workflow syntax * chore: Fix workflow syntax * fix: Workflow linting * chore: Cleanup deprecated job step --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Copilot <[email protected]>
1 parent d8bb39a commit f326080

File tree

8 files changed

+435
-61
lines changed

8 files changed

+435
-61
lines changed

.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@
33
!Dockerfile
44
!tools/entrypoint.sh
55
!tools/install/*.sh
6+
!hooks/
7+
!lib_getopt
8+
!src/
9+
!hooks/*.sh
10+
!lib_getopt

.github/workflows/build-image-test.yaml

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,23 @@ jobs:
1818

1919
strategy:
2020
matrix:
21-
arch:
22-
- amd64
23-
- arm64
2421
include:
2522
- os-name: Ubuntu x64
2623
os: ubuntu-latest
2724
arch: amd64
28-
25+
dockerfile: Dockerfile
2926
- os-name: Ubuntu ARM
3027
os: ubuntu-24.04-arm
3128
arch: arm64
29+
dockerfile: Dockerfile
30+
- os-name: Ubuntu x64 (tools)
31+
os: ubuntu-latest
32+
arch: amd64
33+
dockerfile: Dockerfile.tools
34+
- os-name: Ubuntu ARM (tools)
35+
os: ubuntu-24.04-arm
36+
arch: arm64
37+
dockerfile: Dockerfile.tools
3238

3339
name: ${{ matrix.os-name }}
3440
runs-on: ${{ matrix.os }}
@@ -45,27 +51,29 @@ jobs:
4551
files: |
4652
.dockerignore
4753
.github/workflows/build-image-test.yaml
48-
Dockerfile
54+
${{ matrix.dockerfile }}
4955
tools/entrypoint.sh
5056
tools/install/*.sh
5157
5258
- name: Set IMAGE environment variable
5359
if: steps.changed-files-specific.outputs.any_changed == 'true'
54-
# Lowercase the org/repo name to allow for workflow to run in forks,
55-
# which owners have uppercase letters in username
56-
run: >-
57-
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY@L}:${{ env.IMAGE_TAG }}"
58-
>> $GITHUB_ENV
60+
run: |
61+
if [[ "${{ matrix.dockerfile }}" == "Dockerfile" ]]; then
62+
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY@L}:${{ env.IMAGE_TAG }}" >> $GITHUB_ENV
63+
else
64+
echo "IMAGE=ghcr.io/${GITHUB_REPOSITORY@L}:${{ env.IMAGE_TAG }}-tools" >> $GITHUB_ENV
65+
fi
5966
6067
- name: Set up Docker Buildx
6168
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
6269
if: steps.changed-files-specific.outputs.any_changed == 'true'
6370

64-
- name: Build if Dockerfile changed
71+
- name: Build if "${{ matrix.dockerfile }}" changed
6572
if: steps.changed-files-specific.outputs.any_changed == 'true'
6673
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
6774
with:
6875
context: .
76+
file: ${{ matrix.dockerfile }}
6977
build-args: |
7078
INSTALL_ALL=true
7179
push: false
@@ -98,8 +106,7 @@ jobs:
98106
IMAGE_NAME: ${{ env.IMAGE }}
99107
run: >-
100108
container-structure-test test
101-
--config ${{ github.workspace
102-
}}/.github/.container-structure-test-config.yaml
109+
--config ${{ github.workspace }}/.github/.container-structure-test-config.yaml
103110
--image "${IMAGE_NAME}"
104111
105112
- name: Dive - check image for waste files
@@ -112,8 +119,9 @@ jobs:
112119

113120
# Can't build both platforms and use --load at the same time
114121
# https://github.com/docker/buildx/issues/59#issuecomment-1433097926
115-
- name: Build Multi-arch docker-image
116-
if: >-
122+
# Build Multi-arch docker-image
123+
- name: Build Multi-arch "${{ matrix.dockerfile }}"
124+
if: >
117125
steps.changed-files-specific.outputs.any_changed == 'true'
118126
&& matrix.os == 'ubuntu-latest'
119127
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
@@ -128,3 +136,17 @@ jobs:
128136
provenance: false
129137
secrets: |
130138
"github_token=${{ secrets.GITHUB_TOKEN }}"
139+
140+
# Only run smoke tests for the tools image
141+
- name: Smoke test tools image
142+
if: >
143+
steps.changed-files-specific.outputs.any_changed == 'true'
144+
&& matrix.os == 'ubuntu-latest'
145+
&& matrix.dockerfile == 'Dockerfile.tools'
146+
env:
147+
TOOLS_IMAGE: ${{ env.IMAGE }}
148+
run: |
149+
echo "Testing tools image: $TOOLS_IMAGE"
150+
docker run --rm "$TOOLS_IMAGE" terraform --version
151+
docker run --rm "$TOOLS_IMAGE" terraform-docs --version
152+
docker run --rm "$TOOLS_IMAGE" tflint --version

.github/workflows/build-image.yaml

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,26 @@ on:
66
types:
77
- created
88
schedule:
9-
- cron: 00 00 * * *
9+
- cron: 00 00 * * 0
1010

1111
permissions:
1212
contents: read
13+
# for docker/build-push-action to publish docker image
14+
packages: write
15+
16+
env:
17+
REGISTRY: ghcr.io
1318

1419
jobs:
1520
docker:
16-
permissions:
17-
# for docker/build-push-action to publish docker image
18-
packages: write
19-
2021
runs-on: ubuntu-latest
22+
strategy:
23+
matrix:
24+
include:
25+
- dockerfile: Dockerfile
26+
image_name: ${{ github.repository }}
27+
- dockerfile: Dockerfile.tools
28+
image_name: ${{ github.repository }}-tools
2129
steps:
2230
- name: Checkout code
2331
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -26,60 +34,48 @@ jobs:
2634

2735
- name: Set up Docker Buildx
2836
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
37+
2938
- name: Login to GitHub Container Registry
3039
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 # v3.5.0
3140
with:
32-
registry: ghcr.io
33-
username: ${{ github.repository_owner }}
41+
registry: ${{ env.REGISTRY }}
42+
username: ${{ github.actor }}
3443
password: ${{ secrets.GITHUB_TOKEN }}
35-
- name: Set tag for image
36-
env:
37-
REF_TYPE: ${{ github.ref_type }}
38-
REF_NAME: ${{ github.ref_name }}
39-
run: >-
40-
echo IMAGE_TAG=$(
41-
[ $REF_TYPE == 'tag' ]
42-
&& echo $REF_NAME
43-
|| echo 'latest'
44-
) >> $GITHUB_ENV
45-
46-
- name: Set IMAGE_REPO environment variable
47-
# Lowercase the org/repo name to allow for workflow to run in forks,
48-
# which owners have uppercase letters in username
49-
run: >-
50-
echo "IMAGE_REPO=ghcr.io/${GITHUB_REPOSITORY@L}" >> $GITHUB_ENV
51-
- name: Set up Docker Buildx
52-
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
5344

54-
- name: Build and Push release
55-
if: github.event_name != 'schedule'
56-
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
45+
- name: Extract metadata (tags, labels) for Docker
46+
id: meta
47+
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f
5748
with:
58-
context: .
59-
build-args: |
60-
INSTALL_ALL=true
61-
platforms: linux/amd64,linux/arm64
62-
push: true
49+
images: ${{ env.REGISTRY }}/${{ matrix.image_name }}
6350
tags: |
64-
${{ env.IMAGE_REPO }}:${{ env.IMAGE_TAG }}
65-
${{ env.IMAGE_REPO }}:latest
66-
# Fix multi-platform: https://github.com/docker/buildx/issues/1533
67-
provenance: false
68-
secrets: |
69-
"github_token=${{ secrets.GITHUB_TOKEN }}"
51+
type=ref,event=branch
52+
type=ref,event=pr
53+
type=sha
54+
type=raw,value=latest,enable={{is_default_branch}}
55+
type=raw,value={{github.ref_name}},enable={{github.ref_type == 'tag'}}
56+
type=raw,value=nightly,enable={{github.event_name == 'schedule'}}
7057
71-
- name: Build and Push nightly
72-
if: github.event_name == 'schedule'
58+
- name: Build and Push release
7359
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
7460
with:
7561
context: .
62+
file: ${{ matrix.dockerfile }}
7663
build-args: |
7764
INSTALL_ALL=true
7865
platforms: linux/amd64,linux/arm64
7966
push: true
80-
tags: |
81-
${{ env.IMAGE_REPO }}:nightly
67+
tags: ${{ steps.meta.outputs.tags }}
68+
labels: ${{ steps.meta.outputs.labels }}
8269
# Fix multi-platform: https://github.com/docker/buildx/issues/1533
8370
provenance: false
84-
secrets: |
85-
"github_token=${{ secrets.GITHUB_TOKEN }}"
71+
72+
- name: Test tools image
73+
if: matrix.dockerfile == 'Dockerfile.tools' && github.event_name != 'schedule'
74+
env:
75+
IMAGE_TAGS: ${{ steps.meta.outputs.tags }}
76+
run: |
77+
IMAGE_TAG=$(echo "$IMAGE_TAGS" | head -n1)
78+
echo "Testing tools image: $IMAGE_TAG"
79+
docker run --rm "$IMAGE_TAG" terraform --version
80+
docker run --rm "$IMAGE_TAG" terraform-docs --version
81+
docker run --rm "$IMAGE_TAG" tflint --version

.pre-commit-hooks.yaml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,85 @@
178178
- --args=terraform
179179
files: \.(tf|tofu)$
180180
require_serial: true
181+
182+
# Docker-based versions of hooks (non-breaking additions)
183+
- id: terraform_fmt_docker
184+
name: Terraform fmt (Docker)
185+
description: >-
186+
Rewrites all Terraform configuration files to a canonical format using Docker.
187+
entry: ghcr.io/actuarysailor/pre-commit-terraform-tools:latest
188+
language: docker_image
189+
args: [terraform, fmt]
190+
files: \.(tf|tofu|tfvars|tftest\.hcl|tfmock\.hcl)$
191+
exclude: \.terraform/.*$
192+
193+
- id: terraform_validate_docker
194+
name: Terraform validate (Docker)
195+
description: Validates all Terraform configuration files using Docker.
196+
require_serial: true
197+
entry: ghcr.io/actuarysailor/pre-commit-terraform-tools:latest
198+
language: docker_image
199+
args: [terraform, validate]
200+
pass_filenames: false
201+
files: \.(tf|tofu|tfvars|terraform\.lock\.hcl)$
202+
exclude: \.terraform/.*$
203+
204+
- id: terraform_tflint_docker
205+
name: Terraform validate with tflint (Docker)
206+
description: Validates all Terraform configuration files with TFLint using
207+
Docker.
208+
require_serial: true
209+
entry: ghcr.io/actuarysailor/pre-commit-terraform-tools:latest
210+
language: docker_image
211+
args: [tflint, --chdir=.]
212+
pass_filenames: false
213+
files: \.(tf|tofu|tfvars)$
214+
exclude: \.terraform/.*$
215+
216+
- id: terraform_docs_docker
217+
name: Terraform docs (Docker)
218+
description: >-
219+
Inserts input and output documentation into README.md using Docker.
220+
require_serial: true
221+
entry: ghcr.io/actuarysailor/pre-commit-terraform-tools:latest
222+
language: docker_image
223+
args: [terraform-docs, markdown, table, ., --output-file, README.md]
224+
pass_filenames: false
225+
files: \.(tf|tofu|terraform\.lock\.hcl)$
226+
exclude: \.terraform/.*$
227+
228+
- id: terraform_checkov_docker
229+
name: Checkov (Docker)
230+
description: Runs checkov on Terraform templates using Docker.
231+
entry: ghcr.io/actuarysailor/pre-commit-terraform-tools:latest
232+
language: docker_image
233+
args: [checkov, -d, .]
234+
pass_filenames: false
235+
always_run: false
236+
files: \.(tf|tofu)$
237+
exclude: \.terraform/.*$
238+
require_serial: true
239+
240+
- id: terraform_trivy_docker
241+
name: Terraform validate with trivy (Docker)
242+
description: >-
243+
Static analysis of Terraform templates to spot potential security issues
244+
using Docker.
245+
require_serial: true
246+
entry: ghcr.io/actuarysailor/pre-commit-terraform-tools:latest
247+
language: docker_image
248+
args: [trivy, config, .]
249+
pass_filenames: false
250+
files: \.(tf|tofu|tfvars)$
251+
exclude: \.terraform/.*$
252+
253+
- id: infracost_breakdown_docker
254+
name: Infracost breakdown (Docker)
255+
description: Check terraform infrastructure cost using Docker.
256+
entry: ghcr.io/actuarysailor/pre-commit-terraform-tools:latest
257+
language: docker_image
258+
args: [infracost, breakdown, --path, .]
259+
pass_filenames: false
260+
require_serial: true
261+
files: \.(tf|tofu|tfvars|hcl)$
262+
exclude: \.terraform/.*$

Dockerfile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ COPY --from=builder /usr/local/lib/python3.12/site-packages/ /usr/local/lib/pyth
135135
# Copy terrascan policies
136136
COPY --from=builder /root/ /root/
137137

138+
# Copy hook scripts for Docker-based hooks
139+
COPY hooks/ /usr/local/bin/hooks/
140+
COPY lib_getopt /usr/local/bin/
141+
COPY src/pre_commit_terraform/ /usr/local/lib/python3.12/site-packages/pre_commit_terraform/
142+
138143
# Install hooks extra deps
139144
RUN if [ "$(grep -o '^terraform-docs SKIPPED$' /usr/bin/tools_versions_info)" = "" ]; then \
140145
apk add --no-cache perl=~5 \
@@ -148,6 +153,11 @@ RUN if [ "$(grep -o '^terraform-docs SKIPPED$' /usr/bin/tools_versions_info)" =
148153

149154
COPY tools/entrypoint.sh /entrypoint.sh
150155

156+
# Copy hook scripts for docker_image language support
157+
COPY hooks/ /usr/bin/hooks/
158+
COPY lib_getopt /usr/bin/lib_getopt
159+
RUN chmod +x /usr/bin/hooks/*.sh
160+
151161
ENV PRE_COMMIT_COLOR=${PRE_COMMIT_COLOR:-always}
152162

153163
ENV INFRACOST_API_KEY=${INFRACOST_API_KEY:-}

0 commit comments

Comments
 (0)