diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..dec7810d
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,31 @@
+# Changelog
+
+## v0.5.0
+
+### Added
+
+* Added new YAML syntax for GitHub Actions.
+
+### Changed
+
+* Completely refactored the codebase into one GitHub Action. Please refer to the README for current usage.
+
+### Deprecated
+
+N/A
+
+### Removed
+
+* Removed all `TF_ACTION` environment variables. Please refer to the README for current usage.
+* Removed HashiCorp Configuration Language (HCL) syntax.
+
+### Fixed
+
+* The actions now use the new YAML syntax. ([#67](https://github.com/hashicorp/terraform-github-actions/issues/67))
+* Added support for Terraform 0.11.14. ([#42](https://github.com/hashicorp/terraform-github-actions/issues/67))
+* Comments will not be posted to pull requests when `terraform plan` contains no changes. ([#29](https://github.com/hashicorp/terraform-github-actions/issues/67))
+* Added ability to specify a Terraform version to use. ([#23](https://github.com/hashicorp/terraform-github-actions/issues/67))
+
+### Security
+
+N/A
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..a336aa76
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,9 @@
+FROM alpine:3
+
+RUN ["/bin/sh", "-c", "apk add --update --no-cache bash ca-certificates curl git jq openssh"]
+
+RUN ["bin/sh", "-c", "mkdir -p /src"]
+
+COPY ["src", "/src/"]
+
+ENTRYPOINT ["/src/main.sh"]
diff --git a/README.md b/README.md
index 4bfb980c..e1d5a31c 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,50 @@
# Terraform GitHub Actions
-These official Terraform GitHub Actions allow you to run `terraform fmt`, `validate`, `plan` and `apply` on your pull requests to help you review, validate and apply Terraform changes.
-## Getting Started
-To get started, check out our documentation: [https://www.terraform.io/docs/github-actions/getting-started/](https://www.terraform.io/docs/github-actions/getting-started/).
+Terraform GitHub Actions allow you to run Terraform commands within GitHub Actions.
-## Actions
+The output of the actions can be viewed from the Actions tab in the main repository view. If the actions are executed on a `pull_request` event, a comment may be posted on the pull request.
-### Fmt Action
-Runs `terraform fmt` and comments back if any files are not formatted correctly.
-
+## Success Criteria
-### Validate Action
-Runs `terraform validate` and comments back on error.
-
+An exit code of `0` is considered a successful execution.
-### Plan Action
-Runs `terraform plan` and comments back with the output.
-
+## Usage
-### Apply Action
-Runs `terraform apply` and comments back with the output.
-
\ No newline at end of file
+Please refer to the examples within the `examples` directory for usage.
+
+## Inputs
+
+| Name | Required | Default | Description |
+|--------------------------|----------|---------|---------------------------------------------|
+| `tf_actions_version` | `true` | | Terraform version to install. |
+| `tf_actions_subcommand` | `true` | | Terraform subcommand to execute. |
+| `tf_actions_working_dir` | `false` | `.` | Terraform working directory. |
+| `tf_actions_comment` | `false` | `true` | Whether or not to comment on pull requests. |
+
+## Outputs
+
+| Name | Description |
+|-------------------------------|------------------------------------------------------|
+| `tf_actions_plan_has_changes` | Whether or not the Terraform plan contained changes. |
+
+## Secrets
+
+| Name | Description |
+|--------------------------|----------------------------------------------------------------------------------------------------------------------|
+| `GITHUB_TOKEN` | The GitHub API token used to post comments to pull requests. Not required if `tf_actions_comment` is set to `false`. |
+
+Other secrets may be needed to authenticate with Terraform backends and providers.
+
+**WARNING:** These secrets could be exposed if the action is executed on a malicious Terraform file. To avoid this, it is recommended to not use this action on public repos or repos where untrusted users can submit pull requests.
+
+## Environment Variables
+
+The usual [Terraform environment variables](https://www.terraform.io/docs/commands/environment-variables.html) are supported. Here are the environments variables that might be the most beneficial.
+
+* [`TF_LOG`](https://www.terraform.io/docs/commands/environment-variables.html#tf_log)
+* [`TF_VAR_name`](https://www.terraform.io/docs/commands/environment-variables.html#tf_var_name)
+* [`TF_CLI_ARGS`](https://www.terraform.io/docs/commands/environment-variables.html#tf_cli_args-and-tf_cli_args_name)
+* [`TF_CLI_ARGS_name`](https://www.terraform.io/docs/commands/environment-variables.html#tf_cli_args-and-tf_cli_args_name)
+* `TF_WORKSPACE`
+
+Other environment variables may be configured to pass data into Terraform backends and providers. If the data is sensitive, consider using [secrets](#secrets) instead.
diff --git a/action.yml b/action.yml
new file mode 100644
index 00000000..dd5183a8
--- /dev/null
+++ b/action.yml
@@ -0,0 +1,25 @@
+name: 'Terraform GitHub Actions'
+description: 'Runs Terraform commands via GitHub Actions.'
+author: 'HashiCorp, Inc. Terraform Team '
+branding:
+ icon: 'terminal'
+ color: 'purple'
+inputs:
+ tf_actions_version:
+ description: 'Terraform version to install.'
+ required: true
+ tf_actions_subcommand:
+ description: 'Terraform subcommand to execute.'
+ required: true
+ tf_actions_working_dir:
+ description: 'Terraform working directory.'
+ default: '.'
+ tf_actions_comment:
+ description: 'Whether or not to comment on pull requests.'
+ default: true
+outputs:
+ tf_actions_plan_has_changes:
+ description: 'Whether or not the Terraform plan contained changes.'
+runs:
+ using: 'docker'
+ image: './Dockerfile'
diff --git a/apply/Dockerfile b/apply/Dockerfile
deleted file mode 100644
index f4d7989d..00000000
--- a/apply/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM hashicorp/terraform:0.12.12
-
-LABEL "com.github.actions.name"="terraform apply"
-LABEL "com.github.actions.description"="Run Terraform Apply"
-LABEL "com.github.actions.icon"="play-circle"
-LABEL "com.github.actions.color"="purple"
-
-LABEL "repository"="https://github.com/hashicorp/terraform-github-actions"
-LABEL "homepage"="http://github.com/hashicorp/terraform-github-actions"
-LABEL "maintainer"="HashiCorp Terraform Team "
-
-RUN apk --update --no-cache add jq curl bash
-
-COPY entrypoint.sh /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
diff --git a/apply/README.md b/apply/README.md
deleted file mode 100644
index f67fdfe3..00000000
--- a/apply/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Terraform Apply Action
-Runs `terraform apply` and comments back on the pull request with the apply output.
-
-See [https://www.terraform.io/docs/github-actions/actions/apply.html](https://www.terraform.io/docs/github-actions/actions/apply.html).
diff --git a/apply/entrypoint.sh b/apply/entrypoint.sh
deleted file mode 100755
index 44df24a2..00000000
--- a/apply/entrypoint.sh
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/bin/sh
-
-# stripcolors takes some output and removes ANSI color codes.
-stripcolors() {
- echo "$1" | sed 's/\x1b\[[0-9;]*m//g'
-}
-
-# wrap takes some output and wraps it in a collapsible markdown section if
-# it's over $TF_ACTION_WRAP_LINES long.
-wrap() {
- if [[ $(echo "$1" | wc -l) -gt ${TF_ACTION_WRAP_LINES:-20} ]]; then
- echo "
-Show Output
-
-\`\`\`
-$1
-\`\`\`
-
-
-"
-else
- echo "
-\`\`\`
-$1
-\`\`\`
-"
-fi
-}
-
-set -e
-
-cd "${TF_ACTION_WORKING_DIR:-.}"
-
-if [[ ! -z "$TF_ACTION_TFE_TOKEN" ]]; then
- cat > ~/.terraformrc << EOF
-credentials "${TF_ACTION_TFE_HOSTNAME:-app.terraform.io}" {
- token = "$TF_ACTION_TFE_TOKEN"
-}
-EOF
-fi
-
-if [[ ! -z "$TF_ACTION_WORKSPACE" ]] && [[ "$TF_ACTION_WORKSPACE" != "default" ]]; then
- terraform workspace select "$TF_ACTION_WORKSPACE"
-fi
-
-set +e
-OUTPUT=$(sh -c "TF_IN_AUTOMATION=true terraform apply -auto-approve -input=false $*" 2>&1)
-SUCCESS=$?
-echo "$OUTPUT"
-set -e
-
-# If PR_DATA is null, then this is not a pull request event and so there's
-# no where to comment.
-PR_DATA=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request)
-if [ "$TF_ACTION_COMMENT" = "1" ] || [ "$TF_ACTION_COMMENT" = "false" ] || [ "$PR_DATA" = "null" ]; then
- exit $SUCCESS
-fi
-
-if [[ "$GITHUB_EVENT_NAME" == 'pull_request' ]]; then
- # Build the comment we'll post to the PR.
- OUTPUT=$(stripcolors "$OUTPUT")
- COMMENT=""
- if [ $SUCCESS -ne 0 ]; then
- OUTPUT=$(wrap "$OUTPUT")
- COMMENT="#### \`terraform apply\` Failed for \`$TF_ACTION_WORKING_DIRECTORY\`
-$OUTPUT
-
-*Workflow: \`$GITHUB_WORKFLOW\`, Action: \`$GITHUB_ACTION\`*"
- else
- # Call wrap to optionally wrap our output in a collapsible markdown section.
- OUTPUT=$(wrap "$OUTPUT")
- COMMENT="#### \`terraform apply\` Success for \`$TF_ACTION_WORKING_DIRECTORY\`
-$OUTPUT
-
-*Workflow: \`$GITHUB_WORKFLOW\`, Action: \`$GITHUB_ACTION\`*"
- fi
-
- # Post the comment.
- PAYLOAD=$(echo '{}' | jq --arg body "$COMMENT" '.body = $body')
- COMMENTS_URL=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.comments_url)
-
- curl -s -S -H "Authorization: token $GITHUB_TOKEN" --header "Content-Type: application/json" --data "$PAYLOAD" "$COMMENTS_URL" > /dev/null
-fi
-
-exit $SUCCESS
diff --git a/assets/apply.png b/assets/apply.png
deleted file mode 100644
index f94c26e5..00000000
Binary files a/assets/apply.png and /dev/null differ
diff --git a/assets/fmt.png b/assets/fmt.png
deleted file mode 100644
index 3a50b4e5..00000000
Binary files a/assets/fmt.png and /dev/null differ
diff --git a/assets/plan.png b/assets/plan.png
deleted file mode 100644
index a013ea84..00000000
Binary files a/assets/plan.png and /dev/null differ
diff --git a/assets/validate.png b/assets/validate.png
deleted file mode 100644
index dc7d8d28..00000000
Binary files a/assets/validate.png and /dev/null differ
diff --git a/base-branch-filter/Dockerfile b/base-branch-filter/Dockerfile
deleted file mode 100644
index e12d8fb0..00000000
--- a/base-branch-filter/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM alpine:latest
-
-LABEL "com.github.actions.name"="base branch filter"
-LABEL "com.github.actions.description"="Filters pull request events based on their base branch."
-LABEL "com.github.actions.icon"="filter"
-LABEL "com.github.actions.color"="purple"
-
-LABEL "repository"="https://github.com/hashicorp/terraform-github-actions"
-LABEL "homepage"="http://github.com/hashicorp/terraform-github-actions"
-LABEL "maintainer"="HashiCorp Terraform Team "
-
-RUN apk --no-cache add jq
-
-COPY entrypoint.sh /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
diff --git a/base-branch-filter/README.md b/base-branch-filter/README.md
deleted file mode 100644
index df68cef1..00000000
--- a/base-branch-filter/README.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# Base Branch Filter
-Filters pull request events depending on the base branch
-The base branch is the branch that the pull request will be merged into.
-
-To use, set `args` to a regular expression that
-will be matched against the destination branch.
-
-Note: This action only works on pull request events.
-
-## Example
-Filter on pull requests that have been merged into `master`:
-```hcl
-workflow "example" {
- resolves = "base-branch-filter"
- # Must be used on pull_request events.
- on = "pull_request"
-}
-
-# First we use another filter to filter to only merged events.
-action "merged-prs-filter" {
- uses = "actions/bin/filter@master"
- args = "merged true"
-}
-
-# Then we use this filter to ensure the branch matches "master".
-action "base-branch-filter" {
- uses = "hashicorp/terraform-github-actions/base-branch-filter@master"
- # We set args to our regex.
- args = "^master$"
- needs = "merged-prs-filter"
-}
-```
diff --git a/base-branch-filter/entrypoint.sh b/base-branch-filter/entrypoint.sh
deleted file mode 100755
index fdd21363..00000000
--- a/base-branch-filter/entrypoint.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-set -e
-
-regex="$*"
-base_branch=$(jq -r .pull_request.base.ref "$GITHUB_EVENT_PATH")
-
-echo "$base_branch" | grep -Eq "$regex" || {
- echo "base branch \"$base_branch\" does not match \"$regex\""
- exit 78
-}
diff --git a/examples/pull_request_no_working_dir/.github/workflows/example.yml b/examples/pull_request_no_working_dir/.github/workflows/example.yml
new file mode 100644
index 00000000..fe00e323
--- /dev/null
+++ b/examples/pull_request_no_working_dir/.github/workflows/example.yml
@@ -0,0 +1,43 @@
+# An example workflow using local Terraform state with no working directory set.
+name: 'Terraform Workflow'
+on:
+ - pull_request
+jobs:
+ root:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/pull_request_no_working_dir/main.tf b/examples/pull_request_no_working_dir/main.tf
new file mode 100644
index 00000000..65507d56
--- /dev/null
+++ b/examples/pull_request_no_working_dir/main.tf
@@ -0,0 +1,5 @@
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/examples/pull_request_remote_backend_name/.github/workflows/example.yml b/examples/pull_request_remote_backend_name/.github/workflows/example.yml
new file mode 100644
index 00000000..5ac3840e
--- /dev/null
+++ b/examples/pull_request_remote_backend_name/.github/workflows/example.yml
@@ -0,0 +1,46 @@
+# An example workflow using the `remote` backend with `name`.
+name: 'Terraform Workflow'
+on:
+ - pull_request
+jobs:
+ remote:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_comment: true
+ env:
+ # TF_CLI_ARGS_init is used to pass the backend configuration to the run.
+ # This way is chosen to replicate how one would use the `remote` backend with Terraform Cloud/Enterprise via automation.
+ TF_CLI_ARGS_init: '-backend-config="token=${{ secrets.TFP_TOKEN }}" -backend-config="organization=CHANGE_ME"'
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/pull_request_remote_backend_name/main.tf b/examples/pull_request_remote_backend_name/main.tf
new file mode 100644
index 00000000..367ccf6c
--- /dev/null
+++ b/examples/pull_request_remote_backend_name/main.tf
@@ -0,0 +1,13 @@
+terraform {
+ backend "remote" {
+ workspaces {
+ name = "github-actions"
+ }
+ }
+}
+
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/examples/pull_request_remote_backend_prefix/.github/workflows/example.yml b/examples/pull_request_remote_backend_prefix/.github/workflows/example.yml
new file mode 100644
index 00000000..654ae92c
--- /dev/null
+++ b/examples/pull_request_remote_backend_prefix/.github/workflows/example.yml
@@ -0,0 +1,54 @@
+# An example workflow using the `remote` backend with `prefix`.
+name: 'Terraform Workflow'
+on:
+ - pull_request
+jobs:
+ remote:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_comment: true
+ env:
+ # TF_CLI_ARGS_init is used to pass the backend configuration to the run.
+ # This way is chosen to replicate how one would use the `remote` backend with Terraform Cloud/Enterprise via automation.
+ TF_CLI_ARGS_init: '-backend-config="token=${{ secrets.TFP_TOKEN }}" -backend-config="organization=CHANGE_ME"'
+ # TF_WORKSPACE is needed to automatically select the workspace.
+ # This is concatenated to the end of the `prefix` defined within the `remote` backend.
+ # This workspace must already exist in Terraform Cloud/Enterprise.
+ TF_WORKSPACE: testing
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_comment: true
+ env:
+ # TF_WORKSPACE is needed to automatically select the workspace.
+ # This is concatenated to the end of the `prefix` defined within the `remote` backend.
+ # This workspace must already exist in Terraform Cloud/Enterprise.
+ TF_WORKSPACE: testing
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/pull_request_remote_backend_prefix/main.tf b/examples/pull_request_remote_backend_prefix/main.tf
new file mode 100644
index 00000000..d94ebc94
--- /dev/null
+++ b/examples/pull_request_remote_backend_prefix/main.tf
@@ -0,0 +1,13 @@
+terraform {
+ backend "remote" {
+ workspaces {
+ prefix = "github-actions-"
+ }
+ }
+}
+
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/examples/pull_request_working_dir/.github/workflows/example.yml b/examples/pull_request_working_dir/.github/workflows/example.yml
new file mode 100644
index 00000000..8975616a
--- /dev/null
+++ b/examples/pull_request_working_dir/.github/workflows/example.yml
@@ -0,0 +1,47 @@
+# An example workflow using local Terraform state with a working directory set.
+name: 'Terraform Workflow'
+on:
+ - pull_request
+jobs:
+ root:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/pull_request_working_dir/nested/main.tf b/examples/pull_request_working_dir/nested/main.tf
new file mode 100644
index 00000000..65507d56
--- /dev/null
+++ b/examples/pull_request_working_dir/nested/main.tf
@@ -0,0 +1,5 @@
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/examples/push_no_working_dir/.github/workflows/example.yml b/examples/push_no_working_dir/.github/workflows/example.yml
new file mode 100644
index 00000000..de6ae40c
--- /dev/null
+++ b/examples/push_no_working_dir/.github/workflows/example.yml
@@ -0,0 +1,53 @@
+# An example workflow using local Terraform state with no working directory set.
+name: 'Terraform Workflow'
+on:
+ push:
+ branches:
+ - master
+jobs:
+ root:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Apply'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'apply'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/push_no_working_dir/main.tf b/examples/push_no_working_dir/main.tf
new file mode 100644
index 00000000..65507d56
--- /dev/null
+++ b/examples/push_no_working_dir/main.tf
@@ -0,0 +1,5 @@
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/examples/push_remote_backend_name/.github/workflows/example.yml b/examples/push_remote_backend_name/.github/workflows/example.yml
new file mode 100644
index 00000000..fe59becc
--- /dev/null
+++ b/examples/push_remote_backend_name/.github/workflows/example.yml
@@ -0,0 +1,56 @@
+# An example workflow using the `remote` backend with `name`.
+name: 'Terraform Workflow'
+on:
+ push:
+ branches:
+ - master
+jobs:
+ remote:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_comment: true
+ env:
+ # TF_CLI_ARGS_init is used to pass the backend configuration to the run.
+ # This way is chosen to replicate how one would use the `remote` backend with Terraform Cloud/Enterprise via automation.
+ TF_CLI_ARGS_init: '-backend-config="token=${{ secrets.TFP_TOKEN }}" -backend-config="organization=CHANGE_ME"'
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Apply'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'apply'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/push_remote_backend_name/main.tf b/examples/push_remote_backend_name/main.tf
new file mode 100644
index 00000000..367ccf6c
--- /dev/null
+++ b/examples/push_remote_backend_name/main.tf
@@ -0,0 +1,13 @@
+terraform {
+ backend "remote" {
+ workspaces {
+ name = "github-actions"
+ }
+ }
+}
+
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/examples/push_remote_backend_prefix/.github/workflows/example.yml b/examples/push_remote_backend_prefix/.github/workflows/example.yml
new file mode 100644
index 00000000..0a527beb
--- /dev/null
+++ b/examples/push_remote_backend_prefix/.github/workflows/example.yml
@@ -0,0 +1,68 @@
+# An example workflow using the `remote` backend with `prefix`.
+name: 'Terraform Workflow'
+on:
+ push:
+ branches:
+ - master
+jobs:
+ remote:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_comment: true
+ env:
+ # TF_CLI_ARGS_init is used to pass the backend configuration to the run.
+ # This way is chosen to replicate how one would use the `remote` backend with Terraform Cloud/Enterprise via automation.
+ TF_CLI_ARGS_init: '-backend-config="token=${{ secrets.TFP_TOKEN }}" -backend-config="organization=CHANGE_ME"'
+ # TF_WORKSPACE is needed to automatically select the workspace.
+ # This is concatenated to the end of the `prefix` defined within the `remote` backend.
+ # This workspace must already exist in Terraform Cloud/Enterprise.
+ TF_WORKSPACE: testing
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_comment: true
+ env:
+ # TF_WORKSPACE is needed to automatically select the workspace.
+ # This is concatenated to the end of the `prefix` defined within the `remote` backend.
+ # This workspace must already exist in Terraform Cloud/Enterprise.
+ TF_WORKSPACE: testing
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Apply'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'apply'
+ tf_actions_comment: true
+ env:
+ # TF_WORKSPACE is needed to automatically select the workspace.
+ # This is concatenated to the end of the `prefix` defined within the `remote` backend.
+ # This workspace must already exist in Terraform Cloud/Enterprise.
+ TF_WORKSPACE: testing
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/push_remote_backend_prefix/main.tf b/examples/push_remote_backend_prefix/main.tf
new file mode 100644
index 00000000..d94ebc94
--- /dev/null
+++ b/examples/push_remote_backend_prefix/main.tf
@@ -0,0 +1,13 @@
+terraform {
+ backend "remote" {
+ workspaces {
+ prefix = "github-actions-"
+ }
+ }
+}
+
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/examples/push_working_dir/.github/workflows/example.yml b/examples/push_working_dir/.github/workflows/example.yml
new file mode 100644
index 00000000..ee704c49
--- /dev/null
+++ b/examples/push_working_dir/.github/workflows/example.yml
@@ -0,0 +1,58 @@
+# An example workflow using local Terraform state with a working directory set.
+name: 'Terraform Workflow'
+on:
+ push:
+ branches:
+ - master
+jobs:
+ root:
+ name: 'Terraform Actions'
+ runs-on: ubuntu-latest
+ steps:
+ - name: 'Checkout'
+ uses: actions/checkout@master
+ - name: 'Terraform Format'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'fmt'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Init'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'init'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Validate'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'validate'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Plan'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'plan'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: 'Terraform Apply'
+ uses: hashicorp/terraform-github-actions@master
+ with:
+ tf_actions_version: 0.12.13
+ tf_actions_subcommand: 'apply'
+ tf_actions_working_dir: 'nested'
+ tf_actions_comment: true
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/examples/push_working_dir/nested/main.tf b/examples/push_working_dir/nested/main.tf
new file mode 100644
index 00000000..65507d56
--- /dev/null
+++ b/examples/push_working_dir/nested/main.tf
@@ -0,0 +1,5 @@
+resource "null_resource" "root" {
+ triggers = {
+ value = "${timestamp()}"
+ }
+}
diff --git a/fmt/Dockerfile b/fmt/Dockerfile
deleted file mode 100644
index 8357c168..00000000
--- a/fmt/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM hashicorp/terraform:0.12.12
-
-LABEL "com.github.actions.name"="terraform fmt"
-LABEL "com.github.actions.description"="Validate terraform files are formatted"
-LABEL "com.github.actions.icon"="terminal"
-LABEL "com.github.actions.color"="purple"
-
-LABEL "repository"="https://github.com/hashicorp/terraform-github-actions"
-LABEL "homepage"="http://github.com/hashicorp/terraform-github-actions"
-LABEL "maintainer"="HashiCorp Terraform Team "
-
-RUN apk --update --no-cache add jq curl bash
-
-COPY entrypoint.sh /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
diff --git a/fmt/README.md b/fmt/README.md
deleted file mode 100644
index df3ab3be..00000000
--- a/fmt/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Terraform Fmt Action
-Runs `terraform fmt` to validate all Terraform files in a directory are in the canonical format.
- If any files differ, this action will comment back on the pull request with the diffs of each file.
-
-See [https://www.terraform.io/docs/github-actions/actions/fmt.html](https://www.terraform.io/docs/github-actions/actions/fmt.html).
diff --git a/fmt/entrypoint.sh b/fmt/entrypoint.sh
deleted file mode 100755
index 91881e30..00000000
--- a/fmt/entrypoint.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/sh
-
-# stripcolors takes some output and removes ANSI color codes.
-stripcolors() {
- echo "$1" | sed 's/\x1b\[[0-9;]*m//g'
-}
-
-set -e
-cd "${TF_ACTION_WORKING_DIR:-.}"
-
-set +e
-OUTPUT=$(sh -c "terraform fmt -check -list -recursive $*" 2>&1)
-SUCCESS=$?
-echo "$OUTPUT"
-set -e
-
-if [ $SUCCESS -eq 0 ]; then
- exit 0
-fi
-
-if [[ "$GITHUB_EVENT_NAME" == 'pull_request' ]]; then
- if [ "$TF_ACTION_COMMENT" = "1" ] || [ "$TF_ACTION_COMMENT" = "false" ]; then
- exit $SUCCESS
- fi
-
- OUTPUT=$(stripcolors "$OUTPUT")
- if [ $SUCCESS -eq 2 ]; then
- # If it exits with 2, then there was a parse error and the command won't have
- # printed out the files that have failed. In this case we comment back with the
- # whole parse error.
- COMMENT="\`\`\`
-$OUTPUT
-\`\`\`
-"
- else
- # Otherwise the output will contain a list of unformatted filenames.
- # Iterate through each file and build up a comment containing the diff
- # of each file.
- COMMENT=""
- for file in $OUTPUT; do
- FILE_DIFF=$(terraform fmt -no-color -write=false -diff "$file" | sed -n '/@@.*/,//{/@@.*/d;p}')
- COMMENT="$COMMENT
-$file
-
-\`\`\`diff
-$FILE_DIFF
-\`\`\`
-
-"
- done
- fi
-
- COMMENT_WRAPPER="#### \`terraform fmt\` Failed for \`$TF_ACTION_WORKING_DIRECTORY\`
-$COMMENT
-*Workflow: \`$GITHUB_WORKFLOW\`, Action: \`$GITHUB_ACTION\`*
-"
- PAYLOAD=$(echo '{}' | jq --arg body "$COMMENT_WRAPPER" '.body = $body')
- COMMENTS_URL=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.comments_url)
- curl -s -S -H "Authorization: token $GITHUB_TOKEN" --header "Content-Type: application/json" --data "$PAYLOAD" "$COMMENTS_URL" > /dev/null
-fi
-
-exit $SUCCESS
diff --git a/init/Dockerfile b/init/Dockerfile
deleted file mode 100644
index c813dd0f..00000000
--- a/init/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM hashicorp/terraform:0.12.12
-
-LABEL "com.github.actions.name"="terraform init"
-LABEL "com.github.actions.description"="Run terraform init"
-LABEL "com.github.actions.icon"="download"
-LABEL "com.github.actions.color"="purple"
-
-LABEL "repository"="https://github.com/hashicorp/terraform-github-actions"
-LABEL "homepage"="http://github.com/hashicorp/terraform-github-actions"
-LABEL "maintainer"="HashiCorp Terraform Team "
-
-RUN apk --update --no-cache add jq curl bash
-
-COPY entrypoint.sh /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
diff --git a/init/README.md b/init/README.md
deleted file mode 100644
index 7da40be0..00000000
--- a/init/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Terraform Init Action
-Runs `terraform init` to initialize a Terraform working directory. This action will comment back on the pull request on failure.
-
-See [https://www.terraform.io/docs/github-actions/actions/init.html](https://www.terraform.io/docs/github-actions/actions/init.html).
diff --git a/init/entrypoint.sh b/init/entrypoint.sh
deleted file mode 100755
index 97fb4725..00000000
--- a/init/entrypoint.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-
-# stripcolors takes some output and removes ANSI color codes.
-stripcolors() {
- echo "$1" | sed 's/\x1b\[[0-9;]*m//g'
-}
-
-set -e
-cd "${TF_ACTION_WORKING_DIR:-.}"
-
-if [[ ! -z "$TF_ACTION_TFE_TOKEN" ]]; then
- cat > ~/.terraformrc << EOF
-credentials "${TF_ACTION_TFE_HOSTNAME:-app.terraform.io}" {
- token = "$TF_ACTION_TFE_TOKEN"
-}
-EOF
-fi
-
-set +e
-export TF_APPEND_USER_AGENT="terraform-github-actions/1.0"
-OUTPUT=$(sh -c "terraform init -input=false $*" 2>&1)
-SUCCESS=$?
-echo "$OUTPUT"
-set -e
-
-if [ $SUCCESS -eq 0 ]; then
- exit 0
-fi
-
-if [[ "$GITHUB_EVENT_NAME" == 'pull_request' ]]; then
- if [ "$TF_ACTION_COMMENT" = "1" ] || [ "$TF_ACTION_COMMENT" = "false" ]; then
- exit $SUCCESS
- fi
-
- OUTPUT=$(stripcolors "$OUTPUT")
- COMMENT="#### \`terraform init\` Failed for \`$TF_ACTION_WORKING_DIRECTORY\`
-\`\`\`
-$OUTPUT
-\`\`\`
-*Workflow: \`$GITHUB_WORKFLOW\`, Action: \`$GITHUB_ACTION\`*"
- PAYLOAD=$(echo '{}' | jq --arg body "$COMMENT" '.body = $body')
- COMMENTS_URL=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.comments_url)
- curl -s -S -H "Authorization: token $GITHUB_TOKEN" --header "Content-Type: application/json" --data "$PAYLOAD" "$COMMENTS_URL" > /dev/null
-fi
-
-exit $SUCCESS
-
diff --git a/plan/Dockerfile b/plan/Dockerfile
deleted file mode 100644
index 5fe32fdf..00000000
--- a/plan/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM hashicorp/terraform:0.12.12
-
-LABEL "com.github.actions.name"="terraform plan"
-LABEL "com.github.actions.description"="Run terraform plan"
-LABEL "com.github.actions.icon"="book-open"
-LABEL "com.github.actions.color"="purple"
-
-LABEL "repository"="https://github.com/hashicorp/terraform-github-actions"
-LABEL "homepage"="http://github.com/hashicorp/terraform-github-actions"
-LABEL "maintainer"="HashiCorp Terraform Team "
-
-RUN apk --update --no-cache add jq curl bash
-
-COPY entrypoint.sh /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
diff --git a/plan/README.md b/plan/README.md
deleted file mode 100644
index 78603db1..00000000
--- a/plan/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Terraform Plan Action
-Runs `terraform plan` and comments back on the pull request with the plan output.
-
-See [https://www.terraform.io/docs/github-actions/actions/plan.html](https://www.terraform.io/docs/github-actions/actions/plan.html).
diff --git a/plan/entrypoint.sh b/plan/entrypoint.sh
deleted file mode 100755
index bbfb7c4a..00000000
--- a/plan/entrypoint.sh
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/bin/sh
-
-# stripcolors takes some output and removes ANSI color codes.
-stripcolors() {
- echo "$1" | sed 's/\x1b\[[0-9;]*m//g'
-}
-
-# wrap takes some output and wraps it in a collapsible markdown section if
-# it's over $TF_ACTION_WRAP_LINES long.
-wrap() {
- if [[ $(echo "$1" | wc -l) -gt ${TF_ACTION_WRAP_LINES:-20} ]]; then
- echo "
-Show Output
-
-\`\`\`diff
-$1
-\`\`\`
-
-
-"
-else
- echo "
-\`\`\`diff
-$1
-\`\`\`
-"
-fi
-}
-
-set -e
-
-cd "${TF_ACTION_WORKING_DIR:-.}"
-
-if [[ ! -z "$TF_ACTION_TFE_TOKEN" ]]; then
- cat > ~/.terraformrc << EOF
-credentials "${TF_ACTION_TFE_HOSTNAME:-app.terraform.io}" {
- token = "$TF_ACTION_TFE_TOKEN"
-}
-EOF
-fi
-
-if [[ ! -z "$TF_ACTION_WORKSPACE" ]] && [[ "$TF_ACTION_WORKSPACE" != "default" ]]; then
- terraform workspace select "$TF_ACTION_WORKSPACE"
-fi
-
-set +e
-OUTPUT=$(sh -c "TF_IN_AUTOMATION=true terraform plan -detailed-exitcode -input=false $*" 2>&1)
-SUCCESS=$?
-echo "$OUTPUT"
-set -e
-
-# Detailed exit codes of the plan command include:
-# - 0 = Succeeded with empty diff (no changes)
-# - 1 = Error
-# - 2 = Succeeded with non-empty diff (changes present)
-CHANGES_PRESENT=false
-if [ $SUCCESS -eq 2 ]; then
- CHANGES_PRESENT=true
- SUCCESS=0
-fi
-echo ::set-output name=changes-present::$CHANGES_PRESENT
-
-if [ "$TF_ACTION_COMMENT" = "1" ] || [ "$TF_ACTION_COMMENT" = "false" ]; then
- exit $SUCCESS
-fi
-
-# Build the comment we'll post to the PR.
-OUTPUT=$(stripcolors "$OUTPUT")
-COMMENT=""
-if [ $SUCCESS -ne 0 ]; then
- OUTPUT=$(wrap "$OUTPUT")
- COMMENT="#### \`terraform plan\` Failed for \`$TF_ACTION_WORKING_DIRECTORY\`
-$OUTPUT
-
-*Workflow: \`$GITHUB_WORKFLOW\`, Action: \`$GITHUB_ACTION\`*"
-else
- # Remove "Refreshing state..." lines by only keeping output after the
- # delimiter (72 dashes) that represents the end of the refresh stage.
- # We do this to keep the comment output smaller.
- if echo "$OUTPUT" | egrep '^-{72}$'; then
- OUTPUT=$(echo "$OUTPUT" | sed -n -r '/-{72}/,/-{72}/{ /-{72}/d; p }')
- fi
-
- # Remove whitespace at the beginning of the line for added/modified/deleted
- # resources so the diff markdown formatting highlights those lines.
- OUTPUT=$(echo "$OUTPUT" | sed -r -e 's/^ \+/\+/g' | sed -r -e 's/^ ~/~/g' | sed -r -e 's/^ -/-/g')
-
- # Call wrap to optionally wrap our output in a collapsible markdown section.
- OUTPUT=$(wrap "$OUTPUT")
-
- COMMENT="#### \`terraform plan\` Success for \`$TF_ACTION_WORKING_DIRECTORY\`
-$OUTPUT
-
-*Workflow: \`$GITHUB_WORKFLOW\`, Action: \`$GITHUB_ACTION\`*"
-fi
-
-if [[ "$GITHUB_EVENT_NAME" == 'pull_request' ]]; then
- # Post the comment.
- PAYLOAD=$(echo '{}' | jq --arg body "$COMMENT" '.body = $body')
- COMMENTS_URL=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.comments_url)
- curl -s -S -H "Authorization: token $GITHUB_TOKEN" --header "Content-Type: application/json" --data "$PAYLOAD" "$COMMENTS_URL" > /dev/null
-fi
-
-exit $SUCCESS
diff --git a/src/main.sh b/src/main.sh
new file mode 100755
index 00000000..554002ad
--- /dev/null
+++ b/src/main.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+function stripColors {
+ echo "${1}" | sed 's/\x1b\[[0-9;]*m//g'
+}
+
+function parseInputs {
+ # Required inputs
+ if [ "${INPUT_TF_ACTIONS_VERSION}" != "" ]; then
+ tfVersion=${INPUT_TF_ACTIONS_VERSION}
+ else
+ echo "Input terraform_version cannot be empty"
+ exit 1
+ fi
+
+ if [ "${INPUT_TF_ACTIONS_SUBCOMMAND}" != "" ]; then
+ tfSubcommand=${INPUT_TF_ACTIONS_SUBCOMMAND}
+ else
+ echo "Input terraform_subcommand cannot be empty"
+ exit 1
+ fi
+
+ # Optional inputs
+ tfWorkingDir="."
+ if [ "${INPUT_TF_ACTIONS_WORKING_DIR}" != "" ] || [ "${INPUT_TF_ACTIONS_WORKING_DIR}" != "." ]; then
+ tfWorkingDir=${INPUT_TF_ACTIONS_WORKING_DIR}
+ fi
+
+ tfComment=0
+ if [ "${INPUT_TF_ACTIONS_COMMENT}" == "1" ] || [ "${INPUT_TF_ACTIONS_COMMENT}" == "true" ]; then
+ tfComment=1
+ fi
+}
+
+function installTerraform {
+ url="https://releases.hashicorp.com/terraform/${tfVersion}/terraform_${tfVersion}_linux_amd64.zip"
+
+ echo "Downloading Terraform v${tfVersion}"
+ curl -s -S -L -o /tmp/terraform_${tfVersion} ${url}
+ if [ "${?}" -ne 0 ]; then
+ echo "Failed to download Terraform v${tfVersion}"
+ exit 1
+ fi
+ echo "Successfully downloaded Terraform v${tfVersion}"
+
+ echo "Unzipping Terraform v${tfVersion}"
+ unzip -d /usr/local/bin /tmp/terraform_${tfVersion} &> /dev/null
+ if [ "${?}" -ne 0 ]; then
+ echo "Failed to unzip Terraform v${tfVersion}"
+ exit 1
+ fi
+ echo "Successfully unzipped Terraform v${tfVersion}"
+}
+
+function main {
+ # Source the other files to gain access to their functions
+ scriptDir=$(dirname ${0})
+ source ${scriptDir}/terraform_fmt.sh
+ source ${scriptDir}/terraform_init.sh
+ source ${scriptDir}/terraform_validate.sh
+ source ${scriptDir}/terraform_plan.sh
+ source ${scriptDir}/terraform_apply.sh
+
+ parseInputs
+ cd ${GITHUB_WORKSPACE}/${tfWorkingDir}
+
+ case "${tfSubcommand}" in
+ fmt)
+ installTerraform
+ terraformFmt
+ ;;
+ init)
+ installTerraform
+ terraformInit
+ ;;
+ validate)
+ installTerraform
+ terraformValidate
+ ;;
+ plan)
+ installTerraform
+ terraformPlan
+ ;;
+ apply)
+ installTerraform
+ terraformApply
+ ;;
+ *)
+ echo "Error: Must provide a valid value for terraform_subcommand"
+ exit 1
+ ;;
+ esac
+}
+
+main
diff --git a/src/terraform_apply.sh b/src/terraform_apply.sh
new file mode 100755
index 00000000..4f4b824b
--- /dev/null
+++ b/src/terraform_apply.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+function terraformApply {
+ # Gather the output of `terraform apply`.
+ echo "apply: info: applying Terraform configuration in ${tfWorkingDir}"
+ applyOutput=$(terraform apply -auto-approve -input=false 2>&1)
+ applyExitCode=${?}
+
+ # Exit code of 0 indicates success. Print the output and exit.
+ if [ ${applyExitCode} -eq 0 ]; then
+ echo "apply: info: successfully applied Terraform configuration in ${tfWorkingDir}"
+ echo "${applyOutput}"
+ echo
+ exit ${applyExitCode}
+ fi
+
+ # Exit code of !0 indicates failure.
+ echo "apply: error: failed to apply Terraform configuration in ${tfWorkingDir}"
+ echo "${applyOutput}"
+ echo
+
+ # Comment on the pull request if necessary.
+ if [ "$GITHUB_EVENT_NAME" == "pull_request" ] && [ "${tfComment}" == "1" ]; then
+ applyCommentWrapper="#### \`terraform apply\` Failed
+Show Output
+
+\`\`\`
+${applyOutput}
+\`\`\`
+
+
+*Workflow: \`${GITHUB_WORKFLOW}\`, Action: \`${GITHUB_ACTION}\`, Working Directory: \`${tfWorkingDir}\`*"
+
+ applyCommentWrapper=$(stripColors "${applyCommentWrapper}")
+ echo "apply: info: creating JSON"
+ applyPayload=$(echo '{}' | jq --arg body "${applyCommentWrapper}" '.body = $body')
+ applyCommentsURL=$(cat ${GITHUB_EVENT_PATH} | jq -r .pull_request.comments_url)
+ echo "apply: info: commenting on the pull request"
+ curl -s -S -H "Authorization: token ${GITHUB_TOKEN}" --header "Content-Type: application/json" --data "${applyPayload}" "${applyCommentsURL}" > /dev/null
+ fi
+
+ exit ${applyExitCode}
+}
diff --git a/src/terraform_fmt.sh b/src/terraform_fmt.sh
new file mode 100755
index 00000000..e2d533ef
--- /dev/null
+++ b/src/terraform_fmt.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+function terraformFmt {
+ # Gather the output of `terraform fmt`.
+ echo "fmt: info: checking if Terraform files in ${tfWorkingDir} are correctly formatted"
+ fmtOutput=$(terraform fmt -check -write=false -diff -recursive 2>&1)
+ fmtExitCode=${?}
+
+ # Exit code of 0 indicates success. Print the output and exit.
+ if [ ${fmtExitCode} -eq 0 ]; then
+ echo "fmt: info: Terraform files in ${tfWorkingDir} are correctly formatted"
+ echo "${fmtOutput}"
+ echo
+ exit ${fmtExitCode}
+ fi
+
+ # Exit code of 2 indicates a parse error. Print the output and exit.
+ if [ ${fmtExitCode} -eq 2 ]; then
+ echo "fmt: error: failed to parse Terraform files"
+ echo "${fmtOutput}"
+ echo
+ exit ${fmtExitCode}
+ fi
+
+ # Exit code of !0 and !2 indicates failure.
+ echo "fmt: error: Terraform files in ${tfWorkingDir} are incorrectly formatted"
+ echo "${fmtOutput}"
+ echo
+ echo "fmt: error: the following files in ${tfWorkingDir} are incorrectly formatted"
+ fmtFileList=$(terraform fmt -check -write=false -list -recursive 2>&1)
+ echo "${fmtFileList}"
+ echo
+
+ # Comment on the pull request if necessary.
+ if [ "$GITHUB_EVENT_NAME" == "pull_request" ] && [ "${tfComment}" == "1" ]; then
+ fmtComment=""
+ for file in ${fmtFileList}; do
+ fmtFileDiff=$(terraform fmt -check -write=false -diff "$file" | sed -n '/@@.*/,//{/@@.*/d;p}')
+ fmtComment="${fmtComment}
+${tfWorkingDir}/${file}
+
+\`\`\`diff
+${fmtFileDiff}
+\`\`\`
+
+ "
+
+ done
+
+ fmtCommentWrapper="#### \`terraform fmt\` Failed
+${fmtComment}
+*Workflow: \`${GITHUB_WORKFLOW}\`, Action: \`${GITHUB_ACTION}\`, Working Directory: \`${tfWorkingDir}\`*"
+
+ fmtCommentWrapper=$(stripColors "${fmtCommentWrapper}")
+ echo "fmt: info: creating JSON"
+ fmtPayload=$(echo '{}' | jq --arg body "${fmtCommentWrapper}" '.body = $body')
+ fmtCommentsURL=$(cat ${GITHUB_EVENT_PATH} | jq -r .pull_request.comments_url)
+ echo "fmt: info: commenting on the pull request"
+ curl -s -S -H "Authorization: token ${GITHUB_TOKEN}" --header "Content-Type: application/json" --data "${fmtPayload}" "${fmtCommentsURL}" > /dev/null
+ fi
+
+ exit ${fmtExitCode}
+}
diff --git a/src/terraform_init.sh b/src/terraform_init.sh
new file mode 100755
index 00000000..52d82715
--- /dev/null
+++ b/src/terraform_init.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+function terraformInit {
+ # Gather the output of `terraform init`.
+ echo "init: info: initializing Terraform configuration in ${tfWorkingDir}"
+ initOutput=$(terraform init -input=false 2>&1)
+ initExitCode=${?}
+
+ # Exit code of 0 indicates success. Print the output and exit.
+ if [ ${initExitCode} -eq 0 ]; then
+ echo "init: info: successfully initialized Terraform configuration in ${tfWorkingDir}"
+ echo "${initOutput}"
+ echo
+ exit ${initExitCode}
+ fi
+
+ # Exit code of !0 indicates failure.
+ echo "init: error: failed to initialize Terraform configuration in ${tfWorkingDir}"
+ echo "${initOutput}"
+ echo
+
+ # Comment on the pull request if necessary.
+ if [ "$GITHUB_EVENT_NAME" == "pull_request" ] && [ "${tfComment}" == "1" ]; then
+ initCommentWrapper="#### \`terraform init\` Failed
+
+\`\`\`
+${initOutput}
+\`\`\`
+
+*Workflow: \`${GITHUB_WORKFLOW}\`, Action: \`${GITHUB_ACTION}\`, Working Directory: \`${tfWorkingDir}\`*"
+
+ initCommentWrapper=$(stripColors "${initCommentWrapper}")
+ echo "init: info: creating JSON"
+ initPayload=$(echo '{}' | jq --arg body "${initCommentWrapper}" '.body = $body')
+ initCommentsURL=$(cat ${GITHUB_EVENT_PATH} | jq -r .pull_request.comments_url)
+ echo "init: info: commenting on the pull request"
+ curl -s -S -H "Authorization: token ${GITHUB_TOKEN}" --header "Content-Type: application/json" --data "${initPayload}" "${initCommentsURL}" > /dev/null
+ fi
+
+ exit ${initExitCode}
+}
diff --git a/src/terraform_plan.sh b/src/terraform_plan.sh
new file mode 100755
index 00000000..3c78d301
--- /dev/null
+++ b/src/terraform_plan.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+function terraformPlan {
+ # Gather the output of `terraform plan`.
+ echo "plan: info: planning Terraform configuration in ${tfWorkingDir}"
+ planOutput=$(terraform plan -detailed-exitcode -input=false 2>&1)
+ planExitCode=${?}
+ planHasChanges=false
+ planCommentStatus="Failed"
+
+ # Exit code of 0 indicates success with no changes. Print the output and exit.
+ if [ ${planExitCode} -eq 0 ]; then
+ echo "plan: info: successfully planned Terraform configuration in ${tfWorkingDir}"
+ echo "${planOutput}"
+ echo
+ exit ${planExitCode}
+ fi
+
+ # Exit code of 2 indicates success with changes. Print the output, change the
+ # exit code to 0, and mark that the plan has changes.
+ if [ ${planExitCode} -eq 2 ]; then
+ planExitCode=0
+ planHasChanges=true
+ planCommentStatus="Success"
+ echo "plan: info: successfully planned Terraform configuration in ${tfWorkingDir}"
+ echo "${planOutput}"
+ echo
+ if echo "${planOutput}" | egrep '^-{72}$' &> /dev/null; then
+ planOutput=$(echo "${planOutput}" | sed -n -r '/-{72}/,/-{72}/{ /-{72}/d; p }')
+ fi
+ planOutput=$(echo "${planOutput}" | sed -r -e 's/^ \+/\+/g' | sed -r -e 's/^ ~/~/g' | sed -r -e 's/^ -/-/g')
+ fi
+
+ # Exit code of !0 indicates failure.
+ if [ ${planExitCode} -ne 0 ]; then
+ echo "plan: error: failed to plan Terraform configuration in ${tfWorkingDir}"
+ echo "${planOutput}"
+ echo
+ fi
+
+ # Comment on the pull request if necessary.
+ if [ "$GITHUB_EVENT_NAME" == "pull_request" ] && [ "${tfComment}" == "1" ] && ([ "${planHasChanges}" == "true" ] || [ "${planCommentStatus}" == "Failed" ]); then
+ planCommentWrapper="#### \`terraform plan\` ${planCommentStatus}
+Show Output
+
+\`\`\`
+${planOutput}
+\`\`\`
+
+
+*Workflow: \`${GITHUB_WORKFLOW}\`, Action: \`${GITHUB_ACTION}\`, Working Directory: \`${tfWorkingDir}\`*"
+
+ planCommentWrapper=$(stripColors "${planCommentWrapper}")
+ echo "plan: info: creating JSON"
+ planPayload=$(echo '{}' | jq --arg body "${planCommentWrapper}" '.body = $body')
+ planCommentsURL=$(cat ${GITHUB_EVENT_PATH} | jq -r .pull_request.comments_url)
+ echo "plan: info: commenting on the pull request"
+ curl -s -S -H "Authorization: token ${GITHUB_TOKEN}" --header "Content-Type: application/json" --data "${planPayload}" "${planCommentsURL}" > /dev/null
+ fi
+
+ echo ::set-output name=tf_actions_plan_has_changes::${planHasChanges}
+ exit ${planExitCode}
+}
diff --git a/src/terraform_validate.sh b/src/terraform_validate.sh
new file mode 100755
index 00000000..9854d12e
--- /dev/null
+++ b/src/terraform_validate.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+function terraformValidate {
+ # Gather the ouput of `terraform validate`.
+ echo "validate: info: validating Terraform configuration in ${tfWorkingDir}"
+ validateOutput=$(terraform validate 2>&1)
+ validateExitCode=${?}
+
+ # Exit code of 0 indicates success. Print the output and exit.
+ if [ ${validateExitCode} -eq 0 ]; then
+ echo "validate: info: successfully validated Terraform configuration in ${tfWorkingDir}"
+ echo "${validateOutput}"
+ echo
+ exit ${validateExitCode}
+ fi
+
+ # Exit code of !0 indicates failure.
+ echo "validate: error: failed to validate Terraform configuration in ${tfWorkingDir}"
+ echo "${validateOutput}"
+ echo
+
+ # Comment on the pull request if necessary.
+ if [ "$GITHUB_EVENT_NAME" == "pull_request" ] && [ "${tfComment}" == "1" ]; then
+ validateCommentWrapper="#### \`terraform validate\` Failed
+
+\`\`\`
+${validateOutput}
+\`\`\`
+
+*Workflow: \`${GITHUB_WORKFLOW}\`, Action: \`${GITHUB_ACTION}\`, Working Directory: \`${tfWorkingDir}\`*"
+
+ validateCommentWrapper=$(stripColors "${validateCommentWrapper}")
+ echo "validate: info: creating JSON"
+ validatePayload=$(echo '{}' | jq --arg body "${validateCommentWrapper}" '.body = $body')
+ validateCommentsURL=$(cat ${GITHUB_EVENT_PATH} | jq -r .pull_request.comments_url)
+ echo "validate: info: commenting on the pull request"
+ curl -s -S -H "Authorization: token ${GITHUB_TOKEN}" --header "Content-Type: application/json" --data "${validatePayload}" "${validateCommentsURL}" > /dev/null
+ fi
+
+ exit ${validateExitCode}
+}
diff --git a/validate/Dockerfile b/validate/Dockerfile
deleted file mode 100644
index 63242ca7..00000000
--- a/validate/Dockerfile
+++ /dev/null
@@ -1,15 +0,0 @@
-FROM hashicorp/terraform:0.12.12
-
-LABEL "com.github.actions.name"="terraform validate"
-LABEL "com.github.actions.description"="Validate the terraform files in a directory"
-LABEL "com.github.actions.icon"="alert-triangle"
-LABEL "com.github.actions.color"="purple"
-
-LABEL "repository"="https://github.com/hashicorp/terraform-github-actions"
-LABEL "homepage"="http://github.com/hashicorp/terraform-github-actions"
-LABEL "maintainer"="HashiCorp Terraform Team "
-
-RUN apk --update --no-cache add jq curl bash
-
-COPY entrypoint.sh /entrypoint.sh
-ENTRYPOINT ["/entrypoint.sh"]
diff --git a/validate/README.md b/validate/README.md
deleted file mode 100644
index d8546533..00000000
--- a/validate/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Terraform Validate Action
-Runs `terraform validate` to validate the terraform files in a directory.
-
-See [https://www.terraform.io/docs/github-actions/actions/validate.html](https://www.terraform.io/docs/github-actions/actions/validate.html).
diff --git a/validate/entrypoint.sh b/validate/entrypoint.sh
deleted file mode 100755
index edecd73f..00000000
--- a/validate/entrypoint.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/sh
-
-# stripcolors takes some output and removes ANSI color codes.
-stripcolors() {
- echo "$1" | sed 's/\x1b\[[0-9;]*m//g'
-}
-
-set -e
-cd "${TF_ACTION_WORKING_DIR:-.}"
-
-if [[ ! -z "$TF_ACTION_WORKSPACE" ]] && [[ "$TF_ACTION_WORKSPACE" != "default" ]]; then
- terraform workspace select "$TF_ACTION_WORKSPACE"
-fi
-
-set +e
-OUTPUT=$(sh -c "terraform validate $*" 2>&1)
-SUCCESS=$?
-echo "$OUTPUT"
-set -e
-
-if [ $SUCCESS -eq 0 ]; then
- exit 0
-fi
-
-if [[ "$GITHUB_EVENT_NAME" == 'pull_request' ]]; then
- if [ "$TF_ACTION_COMMENT" = "1" ] || [ "$TF_ACTION_COMMENT" = "false" ]; then
- exit $SUCCESS
- fi
-
- OUTPUT=$(stripcolors "$OUTPUT")
- COMMENT="#### \`terraform validate\` Failed for \`$TF_ACTION_WORKING_DIRECTORY\`
-\`\`\`
-$OUTPUT
-\`\`\`
-*Workflow: \`$GITHUB_WORKFLOW\`, Action: \`$GITHUB_ACTION\`*"
- PAYLOAD=$(echo '{}' | jq --arg body "$COMMENT" '.body = $body')
- COMMENTS_URL=$(cat $GITHUB_EVENT_PATH | jq -r .pull_request.comments_url)
- curl -s -S -H "Authorization: token $GITHUB_TOKEN" --header "Content-Type: application/json" --data "$PAYLOAD" "$COMMENTS_URL" > /dev/null
-fi
-
-exit $SUCCESS