From 4ef6ad63b12680fe2d5d2a62fcccc98f54883ba1 Mon Sep 17 00:00:00 2001 From: andreassag <30706568+andreassag@users.noreply.github.com> Date: Fri, 25 Sep 2026 01:42:41 +0200 Subject: [PATCH 1/3] ci: update dependabot for main and develop, add js and docker scanning to codeql --- .github/dependabot.yml | 113 ++++++++++++++++++++++++++++++++--- .github/workflows/codeql.yml | 68 +++++++++++---------- 2 files changed, 141 insertions(+), 40 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b65fa66..1bedc24 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,14 +3,15 @@ version: 2 updates: - # Monitor Go module dependencies + # ========================================================================= + # Go module dependencies — main + # ========================================================================= - package-ecosystem: "gomod" directory: "/" schedule: interval: "weekly" day: "monday" time: "09:00" - # Group all minor and patch updates together groups: go-dependencies: patterns: @@ -18,23 +19,65 @@ updates: update-types: - "minor" - "patch" - # Keep pull requests manageable open-pull-requests-limit: 5 - # Add labels for easy filtering labels: - "dependencies" - "go" - # Target the main branch + - "target:main" target-branch: "main" - # Monitor GitHub Actions versions + # ========================================================================= + # Go module dependencies — develop + # ========================================================================= + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + groups: + go-dependencies: + patterns: + - "*" + update-types: + - "minor" + - "patch" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "go" + - "target:develop" + target-branch: "develop" + + # ========================================================================= + # GitHub Actions versions — main + # ========================================================================= + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + day: "monday" + time: "09:00" + groups: + github-actions: + patterns: + - "*" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "github-actions" + - "target:main" + target-branch: "main" + + # ========================================================================= + # GitHub Actions versions — develop + # ========================================================================= - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" day: "monday" time: "09:00" - # Group all GitHub Actions updates together groups: github-actions: patterns: @@ -43,9 +86,28 @@ updates: labels: - "dependencies" - "github-actions" + - "target:develop" + target-branch: "develop" + + # ========================================================================= + # Dev Container features and images — main + # ========================================================================= + - package-ecosystem: "devcontainers" + directory: "/" + schedule: + interval: "monthly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "devcontainer" + - "target:main" target-branch: "main" - # Monitor Dev Container features and images + # ========================================================================= + # Dev Container features and images — develop + # ========================================================================= - package-ecosystem: "devcontainers" directory: "/" schedule: @@ -56,4 +118,37 @@ updates: labels: - "dependencies" - "devcontainer" - target-branch: "main" \ No newline at end of file + - "target:develop" + target-branch: "develop" + + # ========================================================================= + # Dockerfile base images — main + # ========================================================================= + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "docker" + - "target:main" + target-branch: "main" + + # ========================================================================= + # Dockerfile base images — develop + # ========================================================================= + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "09:00" + open-pull-requests-limit: 5 + labels: + - "dependencies" + - "docker" + - "target:develop" + target-branch: "develop" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 159d4ed..0aa643c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -10,6 +10,10 @@ on: - '**/*.go' - 'go.mod' - 'go.sum' + - '**/*.js' + - '**/*.ts' + - 'Dockerfile' + - 'docker-compose.yml' - '.github/workflows/codeql.yml' pull_request: branches: @@ -20,6 +24,10 @@ on: - '**/*.go' - 'go.mod' - 'go.sum' + - '**/*.js' + - '**/*.ts' + - 'Dockerfile' + - 'docker-compose.yml' - '.github/workflows/codeql.yml' schedule: - cron: '25 8 * * 5' @@ -27,20 +35,10 @@ on: jobs: analyze: name: Analyze (${{ matrix.language }}) - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners (GitHub.com only) - # Consider using larger runners or machines with greater resources for possible analysis time improvements. runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }} permissions: - # required for all workflows security-events: write - - # required to fetch internal or private CodeQL packs packages: read - - # only required for workflows in private repositories actions: read contents: read @@ -50,19 +48,15 @@ jobs: include: - language: go build-mode: autobuild - # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' - # Use `c-cpp` to analyze code written in C, C++ or both - # Use 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, - # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. - # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how - # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + - language: javascript-typescript + build-mode: none + steps: - name: Checkout repository uses: actions/checkout@v7 - name: Setup Go + if: matrix.language == 'go' uses: actions/setup-go@v7 with: go-version-file: 'go.mod' @@ -73,19 +67,7 @@ jobs: with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - name: Run manual build steps if: matrix.build-mode == 'manual' shell: bash @@ -100,4 +82,28 @@ jobs: - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4.37.9 with: - category: "/language:${{matrix.language}}" \ No newline at end of file + category: "/language:${{matrix.language}}" + + docker: + name: Lint (docker) + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Run Hadolint + uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: Dockerfile + format: sarif + output-file: hadolint-results.sarif + no-fail: true + + - name: Upload Hadolint SARIF to Code Scanning + uses: github/codeql-action/upload-sarif@v4.37.9 + with: + sarif_file: hadolint-results.sarif + category: "/tool:hadolint" From 0d1286997c17c3f30e4d9469f1deecfdbaed235e Mon Sep 17 00:00:00 2001 From: andreassag <30706568+andreassag@users.noreply.github.com> Date: Fri, 25 Sep 2026 01:48:28 +0200 Subject: [PATCH 2/3] ci: add Dependabot auto-merge script and GitHub Actions workflow --- .github/scripts/dependabot-automerge.sh | 329 +++++++++++++++++++++ .github/workflows/dependabot-automerge.yml | 87 ++++++ Makefile | 5 +- 3 files changed, 420 insertions(+), 1 deletion(-) create mode 100755 .github/scripts/dependabot-automerge.sh create mode 100644 .github/workflows/dependabot-automerge.yml diff --git a/.github/scripts/dependabot-automerge.sh b/.github/scripts/dependabot-automerge.sh new file mode 100755 index 0000000..d57b921 --- /dev/null +++ b/.github/scripts/dependabot-automerge.sh @@ -0,0 +1,329 @@ +#!/usr/bin/env bash +# ============================================================================= +# dependabot-automerge.sh +# +# Automatically inspects and merges Dependabot pull requests if and only if +# all CI/CodeQL checks have completed and passed. +# +# Usage: +# ./dependabot-automerge.sh [PR_NUMBER_OR_URL] [OPTIONS] +# +# Options: +# -d, --dry-run Inspect checks and report actions without merging +# -w, --watch Wait for in-progress checks to complete +# -t, --timeout SECONDS Max seconds to wait in watch mode (default: 600) +# -i, --interval SECONDS Interval between poll attempts in watch mode (default: 15) +# -m, --method METHOD Merge method: merge | squash | rebase (default: merge) +# -h, --help Show this help message +# ============================================================================= + +set -euo pipefail + +# Default configuration +DRY_RUN=false +WATCH_MODE=false +TIMEOUT_SECS=600 +POLL_INTERVAL=15 +MERGE_METHOD="merge" +TARGET_PR="" + +# Color helpers +if [[ -t 1 ]]; then + GREEN='\033[0;32m' + YELLOW='\033[1;33m' + RED='\033[0;31m' + BLUE='\033[0;34m' + BOLD='\033[1m' + NC='\033[0m' +else + GREEN='' + YELLOW='' + RED='' + BLUE='' + BOLD='' + NC='' +fi + +log_info() { echo -e "${BLUE}[INFO]${NC} $*"; } +log_ok() { echo -e "${GREEN}[OK]${NC} $*"; } +log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } +log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; } + +show_help() { + cat </dev/null 2>&1; then + log_error "GitHub CLI (gh) is required but not installed." + exit 1 +fi + +if ! command -v jq >/dev/null 2>&1; then + log_error "jq is required but not installed." + exit 1 +fi + +# Authenticate check (GH_TOKEN or existing auth) +if [[ -z "${GH_TOKEN:-}" && -z "${GITHUB_TOKEN:-}" ]] && ! gh auth status >/dev/null 2>&1; then + log_error "GitHub CLI is not authenticated. Set GH_TOKEN or run 'gh auth login'." + exit 1 +fi + +# Function to inspect and evaluate checks for a given PR +evaluate_pr_checks() { + local pr_num="$1" + + gh pr view "$pr_num" --json state,number,title,baseRefName,headRefName,isDraft,mergeable,url,author,statusCheckRollup 2>/dev/null +} + +# Function to analyze check rollup json +analyze_checks() { + local pr_json="$1" + + echo "$pr_json" | jq -r ' + def is_completed: + if .__typename == "StatusContext" then + (.state != "PENDING") + else + (.status == "COMPLETED") + end; + + def is_success: + if .__typename == "StatusContext" then + (.state == "SUCCESS") + else + (.status == "COMPLETED" and (.conclusion == "SUCCESS" or .conclusion == "NEUTRAL" or .conclusion == "SKIPPED")) + end; + + def check_name: + if .__typename == "StatusContext" then + .context + else + .name + end; + + def check_state: + if .__typename == "StatusContext" then + .state + else + (.conclusion // .status) + end; + + def checks: (.statusCheckRollup // []); + def total: (checks | length); + def pending: [checks[] | select(is_completed | not) | "\(check_name):\(check_state)"]; + def failed: [checks[] | select(is_completed and (is_success | not)) | "\(check_name):\(check_state)"]; + + { + total: total, + pending_count: (pending | length), + pending_list: pending, + failed_count: (failed | length), + failed_list: failed, + ready_to_merge: (total > 0 and (pending | length) == 0 and (failed | length) == 0) + } + ' +} + +process_single_pr() { + local pr_num="$1" + log_info "Evaluating Pull Request #${BOLD}${pr_num}${NC}..." + + local elapsed=0 + local pr_data="" + local analysis="" + + while true; do + pr_data=$(evaluate_pr_checks "$pr_num" || true) + + if [[ -z "$pr_data" ]]; then + log_error "Could not fetch details for PR #${pr_num}." + return 1 + fi + + local state title base_ref head_ref is_draft mergeable author_login + state=$(echo "$pr_data" | jq -r '.state') + title=$(echo "$pr_data" | jq -r '.title') + base_ref=$(echo "$pr_data" | jq -r '.baseRefName') + head_ref=$(echo "$pr_data" | jq -r '.headRefName') + is_draft=$(echo "$pr_data" | jq -r '.isDraft') + mergeable=$(echo "$pr_data" | jq -r '.mergeable') + author_login=$(echo "$pr_data" | jq -r '.author.login') + + log_info "Title: \"${title}\"" + log_info "State: ${state}" + log_info "Base Branch: ${base_ref}" + log_info "Head Branch: ${head_ref}" + log_info "Author: ${author_login}" + + if [[ "$state" == "MERGED" ]]; then + log_ok "PR #${pr_num} is already MERGED. Nothing to do." + return 0 + fi + + if [[ "$state" == "CLOSED" ]]; then + log_warn "PR #${pr_num} is CLOSED. Skipping." + return 0 + fi + + # Verify Dependabot origin + if [[ "$author_login" != "app/dependabot" && "$author_login" != "dependabot[bot]" && ! "$head_ref" =~ ^dependabot/ ]]; then + log_warn "PR #${pr_num} does not appear to be authored by Dependabot. Skipping for safety." + return 0 + fi + + # Draft check + if [[ "$is_draft" == "true" ]]; then + log_warn "PR #${pr_num} is a draft. Skipping." + return 0 + fi + + # Conflict check + if [[ "$mergeable" == "CONFLICTING" ]]; then + log_error "PR #${pr_num} has merge conflicts with '${base_ref}'. Manual rebase needed. Skipping." + return 0 + fi + + analysis=$(analyze_checks "$pr_data") + local total pending_count failed_count ready_to_merge + total=$(echo "$analysis" | jq -r '.total') + pending_count=$(echo "$analysis" | jq -r '.pending_count') + failed_count=$(echo "$analysis" | jq -r '.failed_count') + ready_to_merge=$(echo "$analysis" | jq -r '.ready_to_merge') + + log_info "CI Status: Total checks: ${total} | Pending: ${pending_count} | Failed: ${failed_count}" + + # If all checks passed + if [[ "$ready_to_merge" == "true" ]]; then + log_ok "All ${total} CI check(s) have PASSED!" + if [[ "$DRY_RUN" == "true" ]]; then + log_warn "[DRY RUN] Would merge PR #${pr_num} into '${base_ref}' using --${MERGE_METHOD} and delete branch '${head_ref}'." + return 0 + fi + + log_info "Executing merge for PR #${pr_num} into '${base_ref}'..." + if gh pr merge "$pr_num" "--${MERGE_METHOD}" --delete-branch; then + log_ok "Successfully merged PR #${pr_num} into '${base_ref}'!" + else + log_error "Failed to merge PR #${pr_num}. Check branch protection or repository merge permissions." + return 1 + fi + return 0 + fi + + # If any checks failed + if [[ "$failed_count" -gt 0 ]]; then + local failed_list + failed_list=$(echo "$analysis" | jq -r '.failed_list | join(", ")') + log_error "PR #${pr_num} has failed check(s): ${failed_list}. Will NOT merge." + return 0 + fi + + # Checks still in progress or none reported yet + if [[ "$WATCH_MODE" == "true" ]]; then + if [[ $elapsed -ge $TIMEOUT_SECS ]]; then + log_warn "Timeout reached (${TIMEOUT_SECS}s) while waiting for PR #${pr_num} checks to finish. Skipping." + return 0 + fi + log_info "Checks still pending. Waiting ${POLL_INTERVAL}s (elapsed: ${elapsed}s / ${TIMEOUT_SECS}s)..." + sleep "$POLL_INTERVAL" + elapsed=$((elapsed + POLL_INTERVAL)) + else + if [[ "$total" -eq 0 ]]; then + log_warn "PR #${pr_num} has no checks reported yet. Skipping." + else + log_warn "PR #${pr_num} has ${pending_count} pending check(s). Use -w/--watch to wait. Skipping." + fi + return 0 + fi + done +} + +# Main entry point +main() { + if [[ -n "$TARGET_PR" ]]; then + process_single_pr "$TARGET_PR" + else + log_info "Searching for open Dependabot pull requests..." + local pr_list + pr_list=$(gh pr list --state open --json number,title,author,headRefName --jq ' + [.[] | select(.author.login == "app/dependabot" or .author.login == "dependabot[bot]" or (.headRefName | startswith("dependabot/"))) | .number] | .[] + ') + + if [[ -z "$pr_list" ]]; then + log_ok "No open Dependabot pull requests found." + exit 0 + fi + + local pr_count + pr_count=$(echo "$pr_list" | wc -l) + log_info "Found ${pr_count} open Dependabot PR(s)." + + for pr in $pr_list; do + echo "------------------------------------------------------------" + process_single_pr "$pr" || true + done + echo "------------------------------------------------------------" + log_ok "Finished processing Dependabot pull requests." + fi +} + +main "$@" diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml new file mode 100644 index 0000000..c6e0072 --- /dev/null +++ b/.github/workflows/dependabot-automerge.yml @@ -0,0 +1,87 @@ +name: Dependabot Auto-merge + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + workflow_run: + workflows: + - "Continuous integration" + - "CodeQL Advanced" + types: + - completed + schedule: + # Run periodically every 30 minutes as a safety net for any passing PRs + - cron: '*/30 * * * *' + workflow_dispatch: + inputs: + pr_number: + description: 'Specific PR number to inspect and merge (optional, leave empty for all)' + required: false + type: string + dry_run: + description: 'Dry run mode (inspect checks without merging)' + required: false + type: boolean + default: false + +permissions: + contents: write + pull-requests: write + checks: read + statuses: read + +jobs: + automerge: + name: Auto-merge Dependabot PRs + runs-on: ubuntu-latest + if: >- + github.event_name == 'workflow_dispatch' || + github.event_name == 'schedule' || + (github.event_name == 'pull_request' && (github.event.pull_request.user.login == 'dependabot[bot]' || startsWith(github.event.pull_request.head.ref, 'dependabot/'))) || + (github.event_name == 'workflow_run' && (github.event.workflow_run.event == 'pull_request' || startsWith(github.event.workflow_run.head_branch, 'dependabot/'))) + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Make script executable + run: chmod +x .github/scripts/dependabot-automerge.sh + + - name: Dependabot metadata + id: metadata + if: github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]' + uses: dependabot/fetch-metadata@v2 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + + - name: Enable GitHub auto-merge + if: github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]' + run: | + echo "Attempting to enable GitHub native auto-merge for PR #${{ github.event.pull_request.number }}..." + gh pr merge "${{ github.event.pull_request.number }}" --auto --merge --delete-branch || true + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Run verification and merge script + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + FLAGS="" + if [[ "${{ inputs.dry_run }}" == "true" ]]; then + FLAGS="--dry-run" + fi + + if [[ -n "${{ inputs.pr_number }}" ]]; then + echo "Running automerge on specified PR #${{ inputs.pr_number }}..." + ./.github/scripts/dependabot-automerge.sh "${{ inputs.pr_number }}" $FLAGS + elif [[ "${{ github.event_name }}" == "pull_request" ]]; then + echo "Running automerge check for PR #${{ github.event.pull_request.number }}..." + ./.github/scripts/dependabot-automerge.sh "${{ github.event.pull_request.number }}" $FLAGS + else + echo "Scanning all open Dependabot PRs..." + ./.github/scripts/dependabot-automerge.sh $FLAGS + fi diff --git a/Makefile b/Makefile index 8940eef..9ff87a0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,8 @@ # Go & Docker targets -.PHONY: build test run vet tidy hooks docker-up docker-down docker-logs docker-build dev +.PHONY: build test run vet tidy hooks docker-up docker-down docker-logs docker-build dev automerge + +automerge: + ./.github/scripts/dependabot-automerge.sh tidy: go mod tidy From d26f50f7be3628e87a7f0e30f80ce81d6de03b3c Mon Sep 17 00:00:00 2001 From: andreassag <30706568+andreassag@users.noreply.github.com> Date: Fri, 25 Sep 2026 01:49:53 +0200 Subject: [PATCH 3/3] ci: extract Docker Hadolint into dedicated workflow --- .github/workflows/codeql.yml | 28 ------------ .github/workflows/dependabot-automerge.yml | 1 + .github/workflows/docker-lint.yml | 52 ++++++++++++++++++++++ 3 files changed, 53 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/docker-lint.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0aa643c..b390856 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -12,8 +12,6 @@ on: - 'go.sum' - '**/*.js' - '**/*.ts' - - 'Dockerfile' - - 'docker-compose.yml' - '.github/workflows/codeql.yml' pull_request: branches: @@ -26,8 +24,6 @@ on: - 'go.sum' - '**/*.js' - '**/*.ts' - - 'Dockerfile' - - 'docker-compose.yml' - '.github/workflows/codeql.yml' schedule: - cron: '25 8 * * 5' @@ -83,27 +79,3 @@ jobs: uses: github/codeql-action/analyze@v4.37.9 with: category: "/language:${{matrix.language}}" - - docker: - name: Lint (docker) - runs-on: ubuntu-latest - permissions: - contents: read - security-events: write - steps: - - name: Checkout repository - uses: actions/checkout@v7 - - - name: Run Hadolint - uses: hadolint/hadolint-action@v3.1.0 - with: - dockerfile: Dockerfile - format: sarif - output-file: hadolint-results.sarif - no-fail: true - - - name: Upload Hadolint SARIF to Code Scanning - uses: github/codeql-action/upload-sarif@v4.37.9 - with: - sarif_file: hadolint-results.sarif - category: "/tool:hadolint" diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index c6e0072..3b5a1bd 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -11,6 +11,7 @@ on: workflows: - "Continuous integration" - "CodeQL Advanced" + - "Docker Lint" types: - completed schedule: diff --git a/.github/workflows/docker-lint.yml b/.github/workflows/docker-lint.yml new file mode 100644 index 0000000..eb3cdae --- /dev/null +++ b/.github/workflows/docker-lint.yml @@ -0,0 +1,52 @@ +name: "Docker Lint" + +on: + push: + branches: + - main + - develop + - feature/** + paths: + - 'Dockerfile' + - '.hadolint.yaml' + - '.github/workflows/docker-lint.yml' + pull_request: + branches: + - main + - develop + - feature/** + paths: + - 'Dockerfile' + - '.hadolint.yaml' + - '.github/workflows/docker-lint.yml' + schedule: + - cron: '25 8 * * 5' + workflow_dispatch: + +permissions: + contents: read + +jobs: + hadolint: + name: Hadolint + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Run Hadolint + uses: hadolint/hadolint-action@v3.1.0 + with: + dockerfile: Dockerfile + format: sarif + output-file: hadolint-results.sarif + no-fail: true + + - name: Upload Hadolint SARIF to Code Scanning + uses: github/codeql-action/upload-sarif@v4.37.9 + with: + sarif_file: hadolint-results.sarif + category: "/tool:hadolint"