diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..c563657
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,7 @@
+.idea
+.github
+.git
+.dockerignore
+Dockerfile
+LICENSE
+README.md
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..3f34fb6
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,10 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "docker"
+ directory: "/"
+ schedule:
+ interval: "daily"
\ No newline at end of file
diff --git a/.github/workflows/build_and_push_docker_image.yml b/.github/workflows/build_and_push_docker_image.yml
new file mode 100644
index 0000000..929164c
--- /dev/null
+++ b/.github/workflows/build_and_push_docker_image.yml
@@ -0,0 +1,52 @@
+name: "Build and push Dockerfile linter Docker image"
+
+on:
+ push:
+ branches:
+ - "main"
+ paths:
+ - ".dockerignore"
+ - "Dockerfile"
+
+permissions:
+ contents: "read"
+ packages: "write"
+ id-token: "write"
+
+env:
+ REGISTRY: "ghcr.io"
+ IMAGE_NAME: "articola-tools/dockerfile-linter"
+
+jobs:
+ build-and-push:
+ runs-on: "ubuntu-latest"
+ # NOTE: building and pushing Docker image of Dockerfile linter take around 5 minutes.
+ # If this job takes more than 15 minutes, it means that something is wrong.
+ timeout-minutes: 15
+ steps:
+ - name: "Checkout ${{ github.event.repository.name }}"
+ uses: "actions/checkout@v4"
+
+ - name: "Add short hash of current commit to environment variables"
+ run: "echo \"CURRENT_COMMIT_SHORT_HASH=$(git rev-parse --short \"$GITHUB_SHA\")\" >> \"$GITHUB_ENV\""
+
+ - name: "Set up Docker Buildx"
+ uses: "docker/setup-buildx-action@v3"
+
+ - name: "Login to Docker registry"
+ uses: "docker/login-action@v3"
+ with:
+ registry: "${{ env.REGISTRY }}"
+ username: "${{ github.actor }}"
+ password: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: "Build and push Dockerfile linter Docker image"
+ uses: "docker/build-push-action@v6"
+ id: "build-and-push"
+ with:
+ context: "."
+ push: true
+ tags: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest,
+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.CURRENT_COMMIT_SHORT_HASH }}"
+ cache-from: "type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
+ cache-to: "type=inline"
diff --git a/.github/workflows/validate_new_changes.yml b/.github/workflows/validate_new_changes.yml
new file mode 100644
index 0000000..21b8fc4
--- /dev/null
+++ b/.github/workflows/validate_new_changes.yml
@@ -0,0 +1,59 @@
+name: "New changes validation"
+
+on:
+ pull_request: # yamllint disable-line rule:empty-values
+
+permissions:
+ contents: "read"
+ packages: "read"
+
+env:
+ REGISTRY: "ghcr.io"
+ IMAGE_NAME: "articola-tools/dockerfile-linter"
+
+jobs:
+ validate-dockerfile-linter-image:
+ runs-on: "ubuntu-latest"
+ # NOTE: building and running Docker image of Dockerfile linter take around 5 minutes.
+ # If this job takes more than 15 minutes, it means that something is wrong.
+ timeout-minutes: 15
+ steps:
+ - name: "Checkout ${{ github.event.repository.name }}"
+ uses: "actions/checkout@v4"
+
+ - name: "Set up Docker Buildx"
+ uses: "docker/setup-buildx-action@v3"
+
+ - name: "Login to Docker registry"
+ uses: "docker/login-action@v3"
+ with:
+ registry: "${{ env.REGISTRY }}"
+ username: "${{ github.actor }}"
+ password: "${{ secrets.GITHUB_TOKEN }}"
+
+ - name: "Build Dockerfile linter Docker image"
+ uses: "docker/build-push-action@v6"
+ with:
+ push: false
+ load: true
+ # NOTE: using another name to don't allow docker to download image from the internet in the next step.
+ tags: "local/dockerfile-linter-pr:latest"
+ cache-from: "type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
+ cache-to: "type=inline"
+
+ - name: "Run local Dockerfile linter"
+ run: "docker run --rm -v ${{ github.workspace }}:/linter_workdir/repo local/dockerfile-linter-pr:latest"
+
+ - name: "Run Trivy vulnerability scanner"
+ uses: "aquasecurity/trivy-action@0.27.0"
+ env:
+ # NOTE: this is needed because sometimes GHCR hits the rate limit, and AWS will be used instead.
+ TRIVY_DB_REPOSITORY: "ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db"
+ with:
+ image-ref: "local/dockerfile-linter-pr:latest"
+ format: "table"
+ exit-code: "1"
+ ignore-unfixed: true
+ vuln-type: "os,library"
+ severity: "CRITICAL,HIGH,MEDIUM,LOW"
+ scanners: "vuln,secret,misconfig"
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/dockerfile-linter.iml b/.idea/dockerfile-linter.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/dockerfile-linter.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..6f29fee
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..736804c
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..b01cd19
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,21 @@
+FROM alpine:3.20
+
+RUN mkdir /linter_workdir
+
+RUN addgroup -S lintergroup && adduser -S linteruser -G lintergroup && chown -R linteruser:lintergroup /linter_workdir
+
+RUN apk add --no-cache wget=1.24.5-r0 \
+ && wget --progress=dot:mega -O /linter_workdir/hadolint https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64 \
+ && chmod +x /linter_workdir/hadolint \
+ && apk del wget
+
+# NOTE: we need to have a separate directory for linter to work only with needed files,
+# not with files from the entire system.
+WORKDIR /linter_workdir
+
+USER linteruser
+
+HEALTHCHECK --timeout=1s --retries=1 CMD /linter_workdir/hadolint --version || exit 1
+
+ENTRYPOINT ["/bin/sh", "-c", "find /linter_workdir/repo -name 'Dockerfile*' -type f | \
+while read -r dockerfile; do /linter_workdir/hadolint \"$dockerfile\"; done"]
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 261eeb9..ff109eb 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright [yyyy] [name of copyright owner]
+ Copyright 2024 Articola Tools
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index 664bb7b..24281e6 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,15 @@
-# dockerfile-linter
\ No newline at end of file
+# Articola Tools' Dockerfile linter
+
+[![image size](https://ghcr-badge.egpl.dev/articola-tools/dockerfile-linter/size?color=dodgerblue)](https://ghcr-badge.egpl.dev/articola-tools/dockerfile-linter/size?color=dodgerblue)
+
+This repo contains Dockerfile with preconfigured [Dockerfile linter](https://github.com/hadolint/hadolint).
+This linter is used in Articola Tools organization's repositories to lint Dockerfile files like
+other linters.
+
+## Usage
+
+Use `ghcr.io/articola-tools/dockerfile-linter` Docker image with `-v ./:/linter_workdir/repo`
+parameter, where `./` - is a path to a folder with files you want to lint.
+
+Example command to use this linter -
+`docker run --rm -v ./:/linter_workdir/repo ghcr.io/articola-tools/dockerfile-linter`