action.yml
Rama develop · réplica de lectura del repositorio original.
---
name: run-digger
description: Manage terraform collaboration
author: Digger
inputs:
local-dev-mode:
description: run digger for local development?
required: false
default: "false"
local-dev-cli-path:
description: The path to where the compiled digger cli on the self-hosted runner exists (absolute path)
required: false
default: "./digger"
ee:
description: use ee cli?
required: false
default: "false"
fips:
description: build with fips140 standard?
required: false
default: "false"
setup-aws:
description: Setup AWS
required: false
default: "false"
aws-access-key-id:
description: AWS access key id
required: false
aws-secret-access-key:
description: AWS secret access key
required: false
aws-role-to-assume:
description: ARN of AWS IAM role to assume using OIDC
required: false
aws-web-identity-token-file:
description: Location of the Web Identity Token File for assuming a role using OIDC
required: false
aws-region:
description: AWS region
required: false
default: us-east-1
aws-role-duration-seconds:
description: AWS role duration in seconds. Acceptable values range from 15 minutes (900 seconds) to 12 hours (43200 seconds).
required: false
default: 3600
setup-google-cloud:
description: Setup google cloud
required: false
default: "false"
google-auth-credentials:
description: Service account key used got Google auth (mutually exclusive with 'google-workload-identity-provider' input)
required: false
google-workload-identity-provider:
description: Workload identity provider to be used for Google OIDC auth (mutually exclusive with 'google-auth-credentials' input)
required: false
google-workload-identity-provider-audience:
description: "'audience' parameter configured in Google's Workload Identity Provider (if specified). To be used when the 'google-workload-identity-provider' input is specified"
required: false
google-service-account:
description: Service account to be used when the 'google-workload-identity-provider' input is specified)
required: false
google-lock-bucket:
description: The GCP bucket to use for locks
required: false
setup-azure:
description: Setup Azure
required: false
default: "false"
azure-client-id:
description: Azure Client ID to be used for Azure OIDC auth
required: false
azure-tenant-id:
description: AzureAD ID of the organization you are using
required: false
azure-subscription-id:
description: Subscription ID of you are using
required: false
setup-terragrunt:
description: Setup terragrunt
required: false
default: "false"
setup-opentofu:
description: Setup OpenToFu
required: false
default: "false"
opentofu-tfe-token:
description: the cli credentials token to use with opentofu
required: false
default: ""
opentofu-tfe-hostname:
description: the cli hostname auth to use with opentofu
required: false
default: ""
setup-pulumi:
description: Setup Pulumi
required: false
default: "false"
terragrunt-version:
description: Terragrunt version
required: false
default: v0.73.7
opentofu-version:
description: OpenTofu version
required: false
default: v1.6.1
pulumi-version:
description: Pulumi version
required: false
default: v3.3.0
setup-terraform:
description: Setup terraform
required: false
default: "false"
terraform-version:
description: Terraform version
required: false
default: v1.5.5
terraform-tfe-token:
description: the cli credentials token to use with opentofu
required: false
default: ""
terraform-tfe-hostname:
description: the cli hostname auth to use with opentofu
required: false
default: ""
configure-checkout:
description: Configure checkout. Beware that this will overwrite any changes in the working directory
required: false
default: "true"
upload-plan-destination:
description: Destination to upload the plan to. azure, gcp, github and aws are currently supported.
required: false
upload-plan-destination-s3-bucket:
description: Name of the destination bucket for AWS S3. Should be provided if destination == aws
required: false
upload-plan-destination-s3-encryption-enabled:
description: If encryption is to be enabled for s3 bucket
required: false
default: "false"
upload-plan-destination-s3-encryption-type:
description: the type of encryption to use for the S3 bucket, either AES256 or KMS
required: false
default: "AES256"
upload-plan-destination-s3-encryption-kms-key-id:
description: for encryption of type KMS you need to specify the KMS key ID to use
required: false
upload-plan-destination-azure-container:
description: Name of the destination storage account container for Azure blob storage. Should be provided if destination == azure
required: false
upload-plan-destination-azure-storage-account:
description: Name of the destination storage account for Azure blob storage. Should be provided if destination == azure
required: false
upload-plan-destination-gcp-bucket:
description: Name of the destination bucket for a GCP bucket. Should be provided if destination == gcp
required: false
setup-checkov:
description: Setup Checkov
required: false
default: "false"
checkov-version:
description: Checkov version
required: false
default: "3.2.22"
disable-locking:
description: Disable locking (deprecated, use pr_locks on digger.yml instead)
required: false
default: "false"
digger-filename:
description: Alternative Digger configuration file name
required: false
digger-private-key:
description: Digger private key (for digger team and next only)
required: false
digger-token:
description: Digger token
required: false
digger-hostname:
description: Digger hostname
required: false
default: "https://cloud.digger.dev"
digger-organisation:
description: The name of your digger organisation
required: false
setup-tfenv:
description: Setup tfenv
required: false
default: "false"
post-plans-as-one-comment:
description: Post plans as one comment
required: false
default: "false"
reporting-strategy:
description: "comments_per_run or latest_run_comment, anything else will default to original behavior of multiple comments"
required: false
default: "comments_per_run"
mode:
description: "manual, drift-detection or otherwise"
required: false
default: ""
no-backend:
description: "run cli-only, without an orchestrator backend"
required: false
default: "false"
command:
description: "digger plan or digger apply in case of manual mode"
required: false
default: ""
project:
description: "project name for digger to run in case of manual mode"
required: false
default: ""
drift-detection-slack-notification-url:
description: "drift-detection slack drift url"
required: false
default: ""
drift-detection-advanced-slack-notification-url:
description: "drift-detection slack drift url (advanced mode, ee only)"
required: false
default: ""
cache-dependencies:
description: "Leverage actions/cache to cache dependencies to speed up execution"
required: false
default: "false"
terraform-cache-dir:
description: "allows overriding of the terraform cache dir which defaults to ${github.workspace}/cache"
required: false
default: ""
cache-dependencies-s3:
description: "Use S3 for caching terraform/terragrunt dependencies"
required: false
default: "false"
cache-dependencies-s3-bucket:
description: "S3 bucket name for caching without the leading s3 (e.g. mybucket)"
required: false
default: ""
cache-dependencies-s3-bucket-prefix:
description: "S3 bucket prefix for caching (e.g. cache)"
required: false
default: ""
cache-dependencies-s3-region:
description: "AWS region for S3 cache bucket"
required: false
default: "us-east-1"
digger-spec:
description: "(orchestrator only) the spec to pass onto digger cli"
required: false
default: ""
digger-version:
description: "Pre-compiled version of digger CLI to install. Must correspond to a valid release tag (vX.Y.Z). This value overrides the version derived from the github.action_ref."
required: false
default: ""
digger-os:
description: "OS variant of the digger CLI to install. Valid configurable values are: windows, linux, darwin, freebsd."
required: false
default: "Linux"
digger-arch:
description: "Architecture of the digger CLI to install. Valid configurable values are: amd64, arm64, 386."
required: false
default: "X64"
log-level:
description: "Log level for digger CLI. Valid values are: DEBUG, INFO, WARN, ERROR."
required: false
default: "INFO"
outputs:
output:
value: ${{ steps.digger.outputs.output }}
description: The terraform output
runs:
using: composite
steps:
- name: digger run ${{github.event.inputs.id}}
run: echo digger run ${{ inputs.id }}
shell: bash
- name: Determine binary mode (local, build, or pre-built)
id: determine-binary-mode
env:
LOCAL_DEV_MODE: ${{ inputs.local-dev-mode }}
INPUT_DIGGER_VERSION: ${{ inputs.digger-version }}
ACTION_REF: ${{ github.action_ref }}
run: |
set -euo pipefail
if [[ ! ( -z "$INPUT_DIGGER_VERSION" || "$INPUT_DIGGER_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ) ]]; then
echo "::error::Invalid digger-version input $INPUT_DIGGER_VERSION. Must be empty string or match vX.Y.Z"
exit 1
fi
if [[ "$LOCAL_DEV_MODE" == "true" ]]; then
BINARY_MODE="local" # Use locally compiled binary (for development)
elif [[ -n "$INPUT_DIGGER_VERSION" || "$ACTION_REF" == v* ]]; then
BINARY_MODE="prebuilt" # Install prebuilt binary from release
else
BINARY_MODE="build" # Build from source at runtime
fi
echo "binary-mode=${BINARY_MODE}" >> ${GITHUB_OUTPUT}
shell: bash
- name: Validate Input Configuration for Google
run: |
if [[ -z ${{ toJSON(inputs.google-auth-credentials) }} && -z "${{ inputs.google-workload-identity-provider }}" ]]; then
echo "Either 'google-auth-credentials' or 'google-workload-identity-provider' input must be specified with 'setup-google-cloud'"
elif [[ ! -z "${{ inputs.google-workload-identity-provider }}" && -z "${{ inputs.google-service-account }}" ]]; then
echo "'google-service-account' input must be specified with 'google-workload-identity-provider'"
else
exit 0
fi
exit 1
shell: bash
if: inputs.setup-google-cloud == 'true'
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
clean: false
ref: refs/pull/${{ github.event.issue.number }}/merge
if: ${{ github.event_name == 'issue_comment' && inputs.configure-checkout == 'true' }}
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
clean: false
if: ${{ github.event_name != 'issue_comment' && inputs.configure-checkout == 'true' }}
- name: Set up Google Auth Using A Service Account Key
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
with:
credentials_json: "${{ inputs.google-auth-credentials }}"
if: ${{ inputs.setup-google-cloud == 'true' && inputs.google-auth-credentials != '' }}
- name: Set up Google Auth Using Workload Identity Federation
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
with:
token_format: access_token
service_account: ${{ inputs.google-service-account }}
workload_identity_provider: ${{ inputs.google-workload-identity-provider }}
audience: ${{ inputs.google-workload-identity-provider-audience }}
if: ${{ inputs.setup-google-cloud == 'true' && inputs.google-workload-identity-provider != '' }}
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@aa5489c8933f4cc7a4f7d45035b3b1440c9c10db # v3.0.1
if: inputs.setup-google-cloud == 'true'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
with:
aws-access-key-id: ${{ inputs.aws-access-key-id }}
aws-secret-access-key: ${{ inputs.aws-secret-access-key }}
aws-region: ${{ inputs.aws-region }}
role-duration-seconds: ${{ inputs.aws-role-duration-seconds }}
if: ${{ inputs.setup-aws == 'true' && inputs.aws-role-to-assume == '' }}
- name: Configure OIDC AWS credentials
uses: aws-actions/configure-aws-credentials@cbe3b392738ccf3f987d68400dafcf4b0624a56c # v6.2.4
with:
role-to-assume: ${{ inputs.aws-role-to-assume }}
aws-region: ${{ inputs.aws-region }}
web-identity-token-file: ${{ inputs.aws-web-identity-token-file }}
role-duration-seconds: ${{ inputs.aws-role-duration-seconds }}
if: ${{ inputs.setup-aws == 'true' && inputs.aws-role-to-assume != '' }}
- name: Configure OIDC Azure credentials
uses: azure/login@a641126d1b8aa4d1fa005f4f92df94a3a4c4c906 # v3.1.0
with:
client-id: ${{ inputs.azure-client-id }}
tenant-id: ${{ inputs.azure-tenant-id }}
subscription-id: ${{ inputs.azure-subscription-id }}
env:
# Disable post-cleanup when Azure is not being used (v2.2.0+ feature)
# See: https://github.com/Azure/login/pull/484
AZURE_LOGIN_POST_CLEANUP: ${{ inputs.setup-azure == 'true' && 'true' || 'false' }}
if: ${{ inputs.setup-azure == 'true' && inputs.azure-client-id != '' }}
# if terraform-cache-dir is set then we set it to that otherwise set it to '${{github.workspace}}/cache'
- name: retrieve cache dir
shell: bash
run: |
CACHE_DIR=${{ inputs.terraform-cache-dir == '' &&
format('{0}/cache', github.workspace) ||
inputs.terraform-cache-dir }}
echo "TF_PLUGIN_CACHE_DIR=$CACHE_DIR" >> $GITHUB_ENV
echo "TG_PROVIDER_CACHE_DIR=$CACHE_DIR" >> $GITHUB_ENV
echo "TERRAGRUNT_PROVIDER_CACHE_DIR=$CACHE_DIR" >> $GITHUB_ENV
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
id: restore_cache
name: restore_cache
with:
path: ${{ env.TF_PLUGIN_CACHE_DIR }}
key: digger-cache
restore-keys: |
digger-cache
if: ${{ inputs.cache-dependencies == 'true' }}
- name: restore-s3-cache
shell: bash
run: |
BUCKET="${{ inputs.cache-dependencies-s3-bucket }}"
REGION="${{ inputs.cache-dependencies-s3-region }}"
PREFIX="${{ inputs.cache-dependencies-s3-bucket-prefix }}"
SCRIPT_PATH="${{ github.action_path }}/scripts/s3-cache-download.bash"
if [ ! -f "$SCRIPT_PATH" ]; then
echo "::error::S3 cache download script not found at $SCRIPT_PATH"
echo "Please make sure the script exists and is properly installed."
exit 1
fi
chmod +x "$SCRIPT_PATH"
"$SCRIPT_PATH" "$BUCKET" "$PREFIX" "$REGION" "$TF_PLUGIN_CACHE_DIR"
if: ${{ inputs.cache-dependencies-s3 == 'true' }}
# Then terraform setup happens...
- name: Setup Terraform
uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1
with:
terraform_version: ${{ inputs.terraform-version }}
terraform_wrapper: false
cli_config_credentials_token: ${{ inputs.terraform-tfe-token || '' }}
cli_config_credentials_hostname: ${{ inputs.terraform-tfe-hostname || 'otaco.app' }}
if: inputs.setup-terraform == 'true'
# rhythmictech/actions-setup-tfenv is unmaintained and still declares node16,
# which GitHub removes from runners on 2026-09-23. This reproduces what it did.
- name: Setup tfenv
shell: bash
run: |
TFENV_DIR="${HOME:-/opt}/.tfenv"
if [ ! -d "$TFENV_DIR" ]; then
git clone --depth 1 https://github.com/tfutils/tfenv.git "$TFENV_DIR"
fi
echo "$TFENV_DIR/bin" >> "$GITHUB_PATH"
if: inputs.setup-tfenv == 'true'
# autero1/action-terragrunt is unmaintained and still declares node20,
# which GitHub removes from runners on 2026-09-23. This reproduces what it did:
# accepts "0.73.7", "v0.73.7" or "latest"; supports linux/darwin/windows on amd64/arm64/386.
- name: Setup Terragrunt
shell: bash
env:
TG_VERSION: ${{ inputs.terragrunt-version }}
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
if [ "$(echo "$TG_VERSION" | tr '[:upper:]' '[:lower:]')" = "latest" ]; then
TG_VERSION=$(curl -fsSL -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/repos/gruntwork-io/terragrunt/releases/latest | \
sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
echo "Latest Terragrunt version: $TG_VERSION"
fi
case "$TG_VERSION" in v*) ;; *) TG_VERSION="v$TG_VERSION";; esac
case "$(uname -s)" in
Linux) OS=linux ;;
Darwin) OS=darwin ;;
MINGW*|MSYS*|CYGWIN*|Windows_NT) OS=windows ;;
*) echo "Unsupported OS: $(uname -s)"; exit 1 ;;
esac
case "$(uname -m)" in
x86_64|amd64) ARCH=amd64 ;;
aarch64|arm64) ARCH=arm64 ;;
i386|i686) ARCH=386 ;;
*) echo "Unsupported architecture: $(uname -m)"; exit 1 ;;
esac
BIN_DIR="$RUNNER_TEMP/terragrunt-bin"
mkdir -p "$BIN_DIR"
EXT=""; [ "$OS" = "windows" ] && EXT=".exe"
URL="https://github.com/gruntwork-io/terragrunt/releases/download/${TG_VERSION}/terragrunt_${OS}_${ARCH}${EXT}"
echo "Downloading Terragrunt ${TG_VERSION} from ${URL}"
curl -fsSL -o "$BIN_DIR/terragrunt${EXT}" "$URL"
chmod +x "$BIN_DIR/terragrunt${EXT}"
echo "$BIN_DIR" >> "$GITHUB_PATH"
"$BIN_DIR/terragrunt${EXT}" --version
if: inputs.setup-terragrunt == 'true'
- name: Setup OpenTofu
uses: opentofu/setup-opentofu@a1320f892987e89d278cc92dc5adc984fb93aca4 # v2.0.2
with:
tofu_version: ${{ inputs.opentofu-version }}
tofu_wrapper: false
cli_config_credentials_token: ${{ inputs.opentofu-tfe-token || '' }}
cli_config_credentials_hostname: ${{ inputs.opentofu-tfe-hostname || 'otaco.app' }}
if: inputs.setup-opentofu == 'true'
- name: Setup Pulumi
uses: pulumi/actions@8e5e406f4007fca908480587cb9893c07090f58d # v7.0.0
with:
tofu_version: ${{ inputs.pulumi-version }}
if: inputs.setup-pulumi == 'true'
- name: Setup Checkov
run: |
python3 -m venv .venv
source .venv/bin/activate
pip3 install --upgrade pip
pip3 install --upgrade setuptools
pip3 install -U checkov==${{ inputs.checkov-version }}
shell: bash
if: inputs.setup-checkov == 'true'
- name: setup go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: "${{ github.action_path }}/cli/go.mod"
cache: false
if: ${{ steps.determine-binary-mode.outputs.binary-mode != 'prebuilt' }}
- name: Determine Golang cache paths
id: golang-env
run: |
echo "build-cache-path=$(go env GOCACHE)" >>"$GITHUB_OUTPUT"
echo "module-cache-path=$(go env GOMODCACHE)" >>"$GITHUB_OUTPUT"
shell: bash
if: ${{ steps.determine-binary-mode.outputs.binary-mode != 'prebuilt' }}
- name: Copy Digger CLI go.sum for cache key
run: |
if [[ "${{ inputs.local-dev-mode }}" == "true" ]]; then
echo "Digger CLI is in local dev mode, skipping go.sum copy"
elif [[ ${{ inputs.ee }} == "true" ]]; then
cp "$GITHUB_ACTION_PATH/ee/cli/go.sum" "$GITHUB_WORKSPACE/.digger.go.sum"
else
cp "$GITHUB_ACTION_PATH/cli/go.sum" "$GITHUB_WORKSPACE/.digger.go.sum"
fi
shell: bash
if: ${{ steps.determine-binary-mode.outputs.binary-mode != 'prebuilt' }}
- name: Adding required env vars for next step
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
github-token: $GITHUB_TOKEN
with:
script: |
core.exportVariable('ACTIONS_CACHE_URL', process.env['ACTIONS_CACHE_URL'])
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env['ACTIONS_RUNTIME_TOKEN'])
core.exportVariable('ACTIONS_RUNTIME_URL', process.env['ACTIONS_RUNTIME_URL'])
- name: create cache dir
run: |
mkdir -p $GITHUB_WORKSPACE/cache
shell: bash
- name: build and run digger
if: ${{ steps.determine-binary-mode.outputs.binary-mode == 'build' }}
shell: bash
env:
PLAN_UPLOAD_DESTINATION: ${{ inputs.upload-plan-destination }}
PLAN_UPLOAD_S3_ENCRYPTION_ENABLED: ${{ inputs.upload-plan-destination-s3-encryption-enabled }}
PLAN_UPLOAD_S3_ENCRYPTION_TYPE: ${{ inputs.upload-plan-destination-s3-encryption-type }}
PLAN_UPLOAD_S3_ENCRYPTION_KMS_ID: ${{ inputs.upload-plan-destination-s3-encryption-kms-key-id }}
PLAN_UPLOAD_AZURE_STORAGE_CONTAINER_NAME: ${{ inputs.upload-plan-destination-azure-container }}
PLAN_UPLOAD_AZURE_STORAGE_ACCOUNT_NAME: ${{ inputs.upload-plan-destination-azure-storage-account }}
GOOGLE_STORAGE_LOCK_BUCKET: ${{ inputs.google-lock-bucket }}
GOOGLE_STORAGE_PLAN_ARTEFACT_BUCKET: ${{ inputs.upload-plan-destination-gcp-bucket }}
AWS_S3_BUCKET: ${{ inputs.upload-plan-destination-s3-bucket }}
ACTIVATE_VENV: ${{ inputs.setup-checkov == 'true' }}
DISABLE_LOCKING: ${{ inputs.disable-locking == 'true' }}
DIGGER_PRIVATE_KEY: ${{ inputs.digger-private-key }}
DIGGER_TOKEN: ${{ inputs.digger-token }}
DIGGER_ORGANISATION: ${{ inputs.digger-organisation }}
DIGGER_HOSTNAME: ${{ inputs.digger-hostname }}
DIGGER_FILENAME: ${{ inputs.digger-filename }}
ACCUMULATE_PLANS: ${{ inputs.post-plans-as-one-comment == 'true' }}
REPORTING_STRATEGY: ${{ inputs.reporting-strategy }}
INPUT_DIGGER_PROJECT: ${{ inputs.project }}
INPUT_DIGGER_MODE: ${{ inputs.mode }}
INPUT_DIGGER_COMMAND: ${{ inputs.command }}
INPUT_DRIFT_DETECTION_SLACK_NOTIFICATION_URL: ${{ inputs.drift-detection-slack-notification-url }}
INPUT_DRIFT_DETECTION_ADVANCED_SLACK_NOTIFICATION_URL: ${{ inputs.drift-detection-advanced-slack-notification-url }}
NO_BACKEND: ${{ inputs.no-backend }}
DEBUG: "true"
TG_PROVIDER_CACHE: ${{ (inputs.cache-dependencies == 'true' || inputs.cache-dependencies-s3 == 'true') && 1 || 0 }}
TERRAGRUNT_PROVIDER_CACHE: ${{ (inputs.cache-dependencies == 'true' || inputs.cache-dependencies-s3 == 'true') && 1 || 0 }}
TF_PLUGIN_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
TG_PROVIDER_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
TERRAGRUNT_PROVIDER_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
DIGGER_RUN_SPEC: ${{inputs.digger-spec}}
DIGGER_LOG_LEVEL: ${{ inputs.log-level }}
run: |
if [[ ${{ inputs.ee }} == "true" ]]; then
cd $GITHUB_ACTION_PATH/ee/cli
else
cd $GITHUB_ACTION_PATH/cli
fi
if [[ ${{ inputs.fips }} == "true" ]]; then
export GODEBUG=fips140=only
export GOFIPS140=v1.0.0
fi
go build -o digger ./cmd/digger
chmod +x digger
PATH=$PATH:$(pwd)
cd $GITHUB_WORKSPACE
digger
- name: download, install, and run digger
if: ${{ steps.determine-binary-mode.outputs.binary-mode == 'prebuilt' }}
env:
DIGGER_VERSION: ${{ inputs.digger-version || github.action_ref }}
DIGGER_OS: ${{ inputs.digger-os }}
DIGGER_ARCH: ${{ inputs.digger-arch }}
PLAN_UPLOAD_DESTINATION: ${{ inputs.upload-plan-destination }}
PLAN_UPLOAD_S3_ENCRYPTION_ENABLED: ${{ inputs.upload-plan-destination-s3-encryption-enabled }}
PLAN_UPLOAD_S3_ENCRYPTION_TYPE: ${{ inputs.upload-plan-destination-s3-encryption-type }}
PLAN_UPLOAD_S3_ENCRYPTION_KMS_ID: ${{ inputs.upload-plan-destination-s3-encryption-kms-key-id }}
PLAN_UPLOAD_AZURE_STORAGE_CONTAINER_NAME: ${{ inputs.upload-plan-destination-azure-container }}
PLAN_UPLOAD_AZURE_STORAGE_ACCOUNT_NAME: ${{ inputs.upload-plan-destination-azure-storage-account }}
GOOGLE_STORAGE_LOCK_BUCKET: ${{ inputs.google-lock-bucket }}
GOOGLE_STORAGE_PLAN_ARTEFACT_BUCKET: ${{ inputs.upload-plan-destination-gcp-bucket }}
AWS_S3_BUCKET: ${{ inputs.upload-plan-destination-s3-bucket }}
ACTIVATE_VENV: ${{ inputs.setup-checkov == 'true' }}
DISABLE_LOCKING: ${{ inputs.disable-locking == 'true' }}
DIGGER_PRIVATE_KEY: ${{ inputs.digger-private-key }}
DIGGER_TOKEN: ${{ inputs.digger-token }}
DIGGER_ORGANISATION: ${{ inputs.digger-organisation }}
DIGGER_HOSTNAME: ${{ inputs.digger-hostname }}
DIGGER_FILENAME: ${{ inputs.digger-filename }}
ACCUMULATE_PLANS: ${{ inputs.post-plans-as-one-comment == 'true' }}
REPORTING_STRATEGY: ${{ inputs.reporting-strategy }}
INPUT_DIGGER_PROJECT: ${{ inputs.project }}
INPUT_DIGGER_MODE: ${{ inputs.mode }}
INPUT_DIGGER_COMMAND: ${{ inputs.command }}
INPUT_DRIFT_DETECTION_SLACK_NOTIFICATION_URL: ${{ inputs.drift-detection-slack-notification-url }}
INPUT_DRIFT_DETECTION_ADVANCED_SLACK_NOTIFICATION_URL: ${{ inputs.drift-detection-advanced-slack-notification-url }}
NO_BACKEND: ${{ inputs.no-backend }}
TG_PROVIDER_CACHE: ${{ (inputs.cache-dependencies == 'true' || inputs.cache-dependencies-s3 == 'true') && 1 || 0 }}
TERRAGRUNT_PROVIDER_CACHE: ${{ (inputs.cache-dependencies == 'true' || inputs.cache-dependencies-s3 == 'true') && 1 || 0 }}
TF_PLUGIN_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
TG_PROVIDER_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
TERRAGRUNT_PROVIDER_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
DIGGER_RUN_SPEC: ${{inputs.digger-spec}}
DIGGER_LOG_LEVEL: ${{ inputs.log-level }}
id: digger
shell: bash
run: |
set -euo pipefail
echo "🔧 Downloading Digger CLI..."
echo "Runner OS: ${{ runner.os }}, Arch: ${{ runner.arch }}, Digger Version: ${DIGGER_VERSION}"
if [[ ${{ inputs.ee }} == "true" ]]; then
if [[ ${{ inputs.fips }} == "true" ]]; then
DOWNLOAD_URL="https://github.com/diggerhq/digger/releases/download/${DIGGER_VERSION}/digger-ee-cli-${DIGGER_OS}-${DIGGER_ARCH}-fips"
else
DOWNLOAD_URL="https://github.com/diggerhq/digger/releases/download/${DIGGER_VERSION}/digger-ee-cli-${DIGGER_OS}-${DIGGER_ARCH}"
fi
else
DOWNLOAD_URL="https://github.com/diggerhq/digger/releases/download/${DIGGER_VERSION}/digger-cli-${DIGGER_OS}-${DIGGER_ARCH}"
fi
echo "Downloading from: $DOWNLOAD_URL"
if ! curl -sL --fail "$DOWNLOAD_URL" -o digger; then
echo "Failed to download Digger CLI from $DOWNLOAD_URL"
echo ""
echo "Possible reasons:"
echo "1. The release ${DIGGER_VERSION} might not exist"
echo "2. Binary for ${{ runner.os }}-${{ runner.arch }} might not be available"
echo "3. Network connectivity issues"
echo ""
echo "Suggestions:"
echo "- Check if release ${DIGGER_VERSION} exists at: https://github.com/diggerhq/digger/releases"
echo "- Verify the architecture combination is supported"
echo "- Try using a different release version"
exit 1
fi
if [[ ! -f digger || ! -s digger ]]; then
echo "Downloaded file is empty or doesn't exist"
exit 1
fi
chmod +x digger
if [[ ! -x digger ]]; then
echo "Failed to make digger executable"
exit 1
fi
echo "Successfully downloaded and prepared Digger CLI"
PATH=$PATH:$(pwd)
cd $GITHUB_WORKSPACE
digger
- name: run digger in local dev mode
if: ${{ steps.determine-binary-mode.outputs.binary-mode == 'local' }}
env:
DIGGER_VERSION: ${{ github.action_ref }}
PLAN_UPLOAD_DESTINATION: ${{ inputs.upload-plan-destination }}
PLAN_UPLOAD_S3_ENCRYPTION_ENABLED: ${{ inputs.upload-plan-destination-s3-encryption-enabled }}
PLAN_UPLOAD_S3_ENCRYPTION_TYPE: ${{ inputs.upload-plan-destination-s3-encryption-type }}
PLAN_UPLOAD_S3_ENCRYPTION_KMS_ID: ${{ inputs.upload-plan-destination-s3-encryption-kms-key-id }}
PLAN_UPLOAD_AZURE_STORAGE_CONTAINER_NAME: ${{ inputs.upload-plan-destination-azure-container }}
PLAN_UPLOAD_AZURE_STORAGE_ACCOUNT_NAME: ${{ inputs.upload-plan-destination-azure-storage-account }}
GOOGLE_STORAGE_LOCK_BUCKET: ${{ inputs.google-lock-bucket }}
GOOGLE_STORAGE_PLAN_ARTEFACT_BUCKET: ${{ inputs.upload-plan-destination-gcp-bucket }}
AWS_S3_BUCKET: ${{ inputs.upload-plan-destination-s3-bucket }}
ACTIVATE_VENV: ${{ inputs.setup-checkov == 'true' }}
DISABLE_LOCKING: ${{ inputs.disable-locking == 'true' }}
DIGGER_PRIVATE_KEY: ${{ inputs.digger-private-key }}
DIGGER_TOKEN: ${{ inputs.digger-token }}
DIGGER_ORGANISATION: ${{ inputs.digger-organisation }}
DIGGER_HOSTNAME: ${{ inputs.digger-hostname }}
DIGGER_FILENAME: ${{ inputs.digger-filename }}
ACCUMULATE_PLANS: ${{ inputs.post-plans-as-one-comment == 'true' }}
REPORTING_STRATEGY: ${{ inputs.reporting-strategy }}
INPUT_DIGGER_PROJECT: ${{ inputs.project }}
INPUT_DIGGER_MODE: ${{ inputs.mode }}
INPUT_DIGGER_COMMAND: ${{ inputs.command }}
INPUT_DRIFT_DETECTION_SLACK_NOTIFICATION_URL: ${{ inputs.drift-detection-slack-notification-url }}
INPUT_DRIFT_DETECTION_ADVANCED_SLACK_NOTIFICATION_URL: ${{ inputs.drift-detection-advanced-slack-notification-url }}
NO_BACKEND: ${{ inputs.no-backend }}
TG_PROVIDER_CACHE: ${{ (inputs.cache-dependencies == 'true' || inputs.cache-dependencies-s3 == 'true') && 1 || 0 }}
TERRAGRUNT_PROVIDER_CACHE: ${{ (inputs.cache-dependencies == 'true' || inputs.cache-dependencies-s3 == 'true') && 1 || 0 }}
TF_PLUGIN_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
TG_PROVIDER_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
TERRAGRUNT_PROVIDER_CACHE_DIR: ${{ env.TF_PLUGIN_CACHE_DIR }}
DIGGER_RUN_SPEC: ${{inputs.digger-spec}}
DIGGER_LOG_LEVEL: ${{ inputs.log-level }}
id: digger-local-run
shell: bash
run: |
set -euo pipefail
cd $GITHUB_WORKSPACE
echo "🚀 Running digger..."
RAW="${{ inputs.local-dev-cli-path }}"
# Validate path to prevent command injection
if [[ "$RAW" =~ [^a-zA-Z0-9_./-] ]]; then
echo "❌ Invalid characters in local-dev-cli-path"
exit 1
fi
if [[ "$RAW" =~ \.\. || "$RAW" == : || "$RAW" != /* ]]; then
echo "❌ traversal/colon/relative not allowed"; exit 1
fi
DIR=$(realpath -- "$RAW") || { echo "❌ not found"; exit 1; }
[[ -d "$DIR" ]] || { echo "❌ not a dir"; exit 1; }
BIN="$DIR/digger"
[[ -x "$BIN" ]] || { echo "❌ digger not executable at $BIN"; exit 1; }
$BIN
echo "✅ digger completed"
- uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
name: cache-save
if: ${{ always() && inputs.cache-dependencies == 'true' && steps.restore_cache.outputs.cache-hit != 'true' }}
with:
path: ${{ env.TF_PLUGIN_CACHE_DIR }}
key: digger-cache-${{ hashFiles('**/cache') }}
- name: save-s3-cache
shell: bash
run: |
BUCKET="${{ inputs.cache-dependencies-s3-bucket }}"
REGION="${{ inputs.cache-dependencies-s3-region }}"
PREFIX="${{ inputs.cache-dependencies-s3-bucket-prefix }}"
SCRIPT_PATH="${{ github.action_path }}/scripts/s3-cache-upload.bash"
if [ ! -f "$SCRIPT_PATH" ]; then
echo "::error::S3 cache upload script not found at $SCRIPT_PATH"
echo "Please make sure the script exists and is properly installed."
exit 1
fi
chmod +x "$SCRIPT_PATH"
"$SCRIPT_PATH" "$BUCKET" "$PREFIX" "$REGION" "$TF_PLUGIN_CACHE_DIR"
if: ${{ always() && inputs.cache-dependencies-s3 == 'true' }}
branding:
icon: globe
color: purple