Merge branch 'main' into use-tool-versions

This commit is contained in:
Luke van der Hoeven 2024-06-10 17:33:01 -04:00 committed by GitHub
commit bf31c69041
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 4601 additions and 4960 deletions

6
.changes/3.1.0.md Normal file
View file

@ -0,0 +1,6 @@
## 3.1.0 (2024-04-23)
ENHANCEMENTS:
* Automatically fallback to darwin/amd64 for Terraform versions before 1.0.2 as releases for darwin/arm64 are not available ([#409](https://github.com/hashicorp/setup-terraform/issues/409))

6
.changes/3.1.1.md Normal file
View file

@ -0,0 +1,6 @@
## 3.1.1 (2024-05-07)
BUG FIXES:
* wrapper: Fix wrapper to output to stdout and stderr immediately when data is received ([#395](https://github.com/hashicorp/setup-terraform/issues/395))

View file

@ -1,40 +0,0 @@
# Based on https://github.com/leonsteinhaeuser/project-beta-automations
name: "Add Issues/PRs to TF Provider DevEx team board"
on:
issues:
types: [opened, reopened]
pull_request_target:
# NOTE: The way content is added to project board is equivalent to an "upsert".
# Calling it multiple times will be idempotent.
#
# See https://securitylab.github.com/research/github-actions-preventing-pwn-requests/
# to see the reasoning behind using `pull_request_target` instead of `pull_request`
types: [opened, reopened, ready_for_review]
jobs:
add-content-to-project:
name: "Add Content to project"
runs-on: ubuntu-latest
steps:
- name: "Set Issue to 'Priority = Triage Next'"
uses: leonsteinhaeuser/project-beta-automations@939000fb1900c9fc4f7b5058a09d9f833ebc6859 # v2.2.1
if: github.event_name == 'issues'
with:
gh_token: ${{ secrets.TF_DEVEX_PROJECT_GITHUB_TOKEN }}
organization: "hashicorp"
project_id: 99 #< https://github.com/orgs/hashicorp/projects/99
resource_node_id: ${{ github.event.issue.node_id }}
operation_mode: custom_field
custom_field_values: '[{\"name\":\"Priority\",\"type\":\"single_select\",\"value\":\"Triage Next\"}]'
- name: "Set Pull Request to 'Priority = Triage Next'"
uses: leonsteinhaeuser/project-beta-automations@939000fb1900c9fc4f7b5058a09d9f833ebc6859 # v2.2.1
if: github.event_name == 'pull_request'
with:
gh_token: ${{ secrets.TF_DEVEX_PROJECT_GITHUB_TOKEN }}
organization: "hashicorp"
project_id: 99 #< https://github.com/orgs/hashicorp/projects/99
resource_node_id: ${{ github.event.pull_request.node_id }}
operation_mode: custom_field
custom_field_values: '[{\"name\":\"Priority\",\"type\":\"single_select\",\"value\":\"Triage Next\"}]'

View file

@ -15,7 +15,7 @@ jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: miniscruff/changie-action@6dcc2533cac0495148ed4046c438487e4dceaa23 # v2.0.0
with:
version: latest

View file

@ -11,7 +11,7 @@ jobs:
copywrite:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: hashicorp/setup-copywrite@867a1a2a064a0626db322392806428f7dc59cb3e # v1.1.2
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- uses: hashicorp/setup-copywrite@32638da2d4e81d56a0764aa1547882fc4d209636 # v1.1.3
- run: copywrite headers --plan
- run: copywrite license --plan

11
.github/workflows/data/delay/main.tf vendored Normal file
View file

@ -0,0 +1,11 @@
resource "null_resource" "previous" {}
resource "time_sleep" "wait_30_seconds" {
depends_on = [null_resource.previous]
create_duration = "30s"
}
resource "null_resource" "next" {
depends_on = [time_sleep.wait_30_seconds]
}

View file

@ -0,0 +1,21 @@
# DO NOT EDIT - This GitHub Workflow is managed by automation
# https://github.com/hashicorp/terraform-devex-repos
name: Issue Comment Triage
on:
issue_comment:
types: [created]
jobs:
issue_comment_triage:
runs-on: ubuntu-latest
env:
# issue_comment events are triggered by comments on issues and pull requests. Checking the
# value of github.event.issue.pull_request tells us whether the issue is an issue or is
# actually a pull request, allowing us to dynamically set the gh subcommand:
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#issue_comment-on-issues-only-or-pull-requests-only
COMMAND: ${{ github.event.issue.pull_request && 'pr' || 'issue' }}
GH_TOKEN: ${{ github.token }}
steps:
- name: 'Remove waiting-response on comment'
run: gh ${{ env.COMMAND }} edit ${{ github.event.issue.html_url }} --remove-label waiting-response

View file

@ -1,39 +0,0 @@
on:
issues:
types: [closed, deleted, reopened]
pull_request_target:
types: [closed, reopened]
name: Jira Sync
jobs:
sync:
runs-on: ubuntu-latest
name: Jira sync
steps:
- name: Login
uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1
if: contains(github.event.pull_request.labels.*.name, 'tf-devex-triage') || contains(github.event.issue.labels.*.name, 'tf-devex-triage')
env:
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
- name: Search for existing issue
id: search
if: contains(github.event.pull_request.labels.*.name, 'tf-devex-triage') || contains(github.event.issue.labels.*.name, 'tf-devex-triage')
uses: tomhjp/gh-action-jira-search@04700b457f317c3e341ce90da5a3ff4ce058f2fa # v0.2.2
with:
jql: 'project="TFECO" and "Team (R&D)[Labels]"="TF-DevEx" and description ~ "${{ github.event.issue.html_url || github.event.pull_request.html_url }}" and labels in (Github)'
- name: Close task
if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue
uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1
with:
issue: ${{ steps.search.outputs.issue }}
transition: "Closed"
- name: Reopen task
if: github.event.action == 'reopened' && steps.search.outputs.issue
uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1
with:
issue: ${{ steps.search.outputs.issue }}
transition: "To Do"

21
.github/workflows/lock.yml vendored Normal file
View file

@ -0,0 +1,21 @@
# DO NOT EDIT - This GitHub Workflow is managed by automation
# https://github.com/hashicorp/terraform-devex-repos
name: 'Lock Threads'
on:
schedule:
- cron: '0 10 * * *'
jobs:
lock:
runs-on: ubuntu-latest
steps:
# NOTE: When TSCCR updates the GitHub action version, update the template workflow file to avoid drift:
# https://github.com/hashicorp/terraform-devex-repos/blob/main/modules/repo/workflows/lock.tftpl
- uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1
with:
github-token: ${{ github.token }}
issue-inactive-days: '30'
issue-lock-reason: resolved
pr-inactive-days: '30'
pr-lock-reason: resolved

View file

@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0
# Avoid persisting GITHUB_TOKEN credentials as they take priority over our service account PAT for `git push` operations
@ -62,7 +62,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0
# Default input is the SHA that initially triggered the workflow. As we created a new commit in the previous job,
@ -91,7 +91,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
fetch-depth: 0
# Default input is the SHA that initially triggered the workflow. As we created a new commit in the previous job,
@ -117,7 +117,7 @@ jobs:
permissions:
contents: write # Needed to create GitHub release
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
with:
ref: ${{ inputs.versionNumber }}
fetch-depth: 0

View file

@ -1,37 +0,0 @@
on:
issues:
types: [labeled]
name: Jira Sync
jobs:
sync:
runs-on: ubuntu-latest
name: Jira sync
steps:
- name: Login
uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1
if: github.event.label.name == 'tf-devex-triage'
env:
JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
- name: Search for existing issue
id: search
if: github.event.label.name == 'tf-devex-triage'
uses: tomhjp/gh-action-jira-search@04700b457f317c3e341ce90da5a3ff4ce058f2fa # v0.2.2
with:
jql: 'project="TFECO" and "Team (R&D)[Labels]"="TF-DevEx" and description ~ "${{ github.event.issue.html_url || github.event.pull_request.html_url }}" and labels in (Github)'
- name: Create task in DevEx board
if: github.event.label.name == 'tf-devex-triage' && !steps.search.outputs.issue
uses: atlassian/gajira-create@59e177c4f6451399df5b4911c2211104f171e669 # v3.0.1
with:
project: TFECO
issuetype: "Task"
summary: "[GH] ${{ github.event.issue.title || github.event.pull_request.title }}"
description: "${{ github.event.issue.html_url || github.event.pull_request.html_url }} \n Synced by Github Actions, tagged by ${{ github.actor }}"
# customfield_10091 is Team (R&D)
fields: '{"customfield_10091": ["TF-DevEx"], "labels": ["Github"]}'

View file

@ -20,7 +20,7 @@ jobs:
terraform-versions: [0.11.14, latest]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform - ${{ matrix['terraform-versions'] }}
uses: ./
@ -44,7 +44,7 @@ jobs:
terraform-versions: [0.11.14, latest]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform (no wrapper) - ${{ matrix['terraform-versions'] }}
uses: ./
@ -69,7 +69,7 @@ jobs:
terraform-versions: [~0.12, 0.12.x, <0.13.0]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform - ${{ matrix['terraform-versions'] }}
uses: ./
@ -88,7 +88,7 @@ jobs:
terraform-versions: [~0.12, 0.12.x, <0.13.0]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform (no wrapper) - ${{ matrix['terraform-versions'] }}
uses: ./
@ -100,7 +100,7 @@ jobs:
run: terraform version | grep 'Terraform v0\.12'
terraform-credentials-cloud:
name: 'Terraform Cloud Credentials'
name: 'HCP Terraform Credentials'
runs-on: ${{ matrix.os }}
strategy:
matrix:
@ -109,7 +109,7 @@ jobs:
TF_CLOUD_API_TOKEN: 'XXXXXXXXXXXXXX.atlasv1.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -138,7 +138,7 @@ jobs:
TF_CLOUD_API_TOKEN: 'XXXXXXXXXXXXXX.atlasv1.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -166,7 +166,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -189,7 +189,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -220,7 +220,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -257,7 +257,7 @@ jobs:
working-directory: ./.github/workflows/data/local
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -287,7 +287,7 @@ jobs:
working-directory: ./.github/workflows/data/local
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -304,7 +304,6 @@ jobs:
id: plan
run: terraform plan
terraform-stdout-wrapper:
name: 'Terraform STDOUT'
runs-on: ${{ matrix.os }}
@ -317,7 +316,7 @@ jobs:
working-directory: ./.github/workflows/data/local
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -350,7 +349,7 @@ jobs:
working-directory: ./.github/workflows/data/local
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
@ -370,3 +369,33 @@ jobs:
- name: Terraform Output to JQ
id: output
run: terraform output -json | jq '.pet.value'
# This test has an artificial delay for testing the streaming of STDOUT
terraform-wrapper-delayed-apply:
name: 'Terraform Delayed Apply'
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
defaults:
run:
shell: bash
working-directory: ./.github/workflows/data/delay
steps:
- name: Checkout
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Setup Terraform
uses: ./
with:
terraform_wrapper: true
- name: Terraform Init
run: terraform init
- name: Terraform Format
run: terraform fmt -check
- name: Terraform Apply
id: apply
run: terraform apply -auto-approve

View file

@ -1,3 +1,15 @@
## 3.1.1 (2024-05-07)
BUG FIXES:
* wrapper: Fix wrapper to output to stdout and stderr immediately when data is received ([#395](https://github.com/hashicorp/setup-terraform/issues/395))
## 3.1.0 (2024-04-23)
ENHANCEMENTS:
* Automatically fallback to darwin/amd64 for Terraform versions before 1.0.2 as releases for darwin/arm64 are not available ([#409](https://github.com/hashicorp/setup-terraform/issues/409))
## 3.0.0 (2023-10-30)
NOTES:

View file

@ -6,7 +6,7 @@
The `hashicorp/setup-terraform` action is a JavaScript action that sets up Terraform CLI in your GitHub Actions workflow by:
- Downloading a specific version of Terraform CLI and adding it to the `PATH`.
- Configuring the [Terraform CLI configuration file](https://www.terraform.io/docs/commands/cli-config.html) with a Terraform Cloud/Enterprise hostname and API token.
- Configuring the [Terraform CLI configuration file](https://www.terraform.io/docs/commands/cli-config.html) with a HCP Terraform/Terraform Enterprise hostname and API token.
- Installing a wrapper script to wrap subsequent calls of the `terraform` binary and expose its STDOUT, STDERR, and exit code as outputs named `stdout`, `stderr`, and `exitcode` respectively. (This can be optionally skipped if subsequent steps in the same job do not need to access the results of Terraform commands.)
After you've used the action, subsequent steps in the same job can run arbitrary Terraform commands using [the GitHub Actions `run` syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun). This allows most Terraform commands to work exactly like they do on your local command line.
@ -31,7 +31,7 @@ steps:
terraform_version: "1.1.7"
```
Credentials for Terraform Cloud ([app.terraform.io](https://app.terraform.io/)) can be configured:
Credentials for HCP Terraform ([app.terraform.io](https://app.terraform.io/)) can be configured:
```yaml
steps:
@ -111,7 +111,7 @@ steps:
run: terraform plan -no-color
continue-on-error: true
- uses: actions/github-script@v6
- uses: actions/github-script@v7
if: github.event_name == 'pull_request'
env:
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
@ -179,7 +179,7 @@ steps:
run: terraform plan -no-color
continue-on-error: true
- uses: actions/github-script@v6
- uses: actions/github-script@v7
if: github.event_name == 'pull_request'
env:
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
@ -242,9 +242,9 @@ steps:
The action supports the following inputs:
- `cli_config_credentials_hostname` - (optional) The hostname of a Terraform Cloud/Enterprise instance to
- `cli_config_credentials_hostname` - (optional) The hostname of a HCP Terraform/Terraform Enterprise instance to
place within the credentials block of the Terraform CLI configuration file. Defaults to `app.terraform.io`.
- `cli_config_credentials_token` - (optional) The API token for a Terraform Cloud/Enterprise instance to
- `cli_config_credentials_token` - (optional) The API token for a HCP Terraform/Terraform Enterprise instance to
place within the credentials block of the Terraform CLI configuration file.
- `terraform_version` - (optional) The version of Terraform CLI to install. Instead of a full version string,
you can also specify a constraint string (see [Semver Ranges](https://www.npmjs.com/package/semver#ranges)

View file

@ -3,11 +3,11 @@ description: 'Sets up Terraform CLI in your GitHub Actions workflow.'
author: 'HashiCorp, Inc.'
inputs:
cli_config_credentials_hostname:
description: 'The hostname of a Terraform Cloud/Enterprise instance to place within the credentials block of the Terraform CLI configuration file. Defaults to `app.terraform.io`.'
description: 'The hostname of a HCP Terraform/Terraform Enterprise instance to place within the credentials block of the Terraform CLI configuration file. Defaults to `app.terraform.io`.'
default: 'app.terraform.io'
required: false
cli_config_credentials_token:
description: 'The API token for a Terraform Cloud/Enterprise instance to place within the credentials block of the Terraform CLI configuration file.'
description: 'The API token for a HCP Terraform/Terraform Enterprise instance to place within the credentials block of the Terraform CLI configuration file.'
required: false
terraform_version:
description: 'The version of Terraform CLI to install. Instead of full version string you can also specify constraint string starting with "<" (for example `<1.13.0`) to install the latest version satisfying the constraint. A value of `latest` will install the latest version of Terraform CLI. Defaults to `latest`.'

8400
dist/index.js vendored

File diff suppressed because it is too large Load diff

312
dist/index1.js vendored
View file

@ -11746,6 +11746,132 @@ function onConnectTimeout (socket) {
module.exports = buildConnector
/***/ }),
/***/ 4462:
/***/ ((module) => {
"use strict";
/** @type {Record<string, string | undefined>} */
const headerNameLowerCasedRecord = {}
// https://developer.mozilla.org/docs/Web/HTTP/Headers
const wellknownHeaderNames = [
'Accept',
'Accept-Encoding',
'Accept-Language',
'Accept-Ranges',
'Access-Control-Allow-Credentials',
'Access-Control-Allow-Headers',
'Access-Control-Allow-Methods',
'Access-Control-Allow-Origin',
'Access-Control-Expose-Headers',
'Access-Control-Max-Age',
'Access-Control-Request-Headers',
'Access-Control-Request-Method',
'Age',
'Allow',
'Alt-Svc',
'Alt-Used',
'Authorization',
'Cache-Control',
'Clear-Site-Data',
'Connection',
'Content-Disposition',
'Content-Encoding',
'Content-Language',
'Content-Length',
'Content-Location',
'Content-Range',
'Content-Security-Policy',
'Content-Security-Policy-Report-Only',
'Content-Type',
'Cookie',
'Cross-Origin-Embedder-Policy',
'Cross-Origin-Opener-Policy',
'Cross-Origin-Resource-Policy',
'Date',
'Device-Memory',
'Downlink',
'ECT',
'ETag',
'Expect',
'Expect-CT',
'Expires',
'Forwarded',
'From',
'Host',
'If-Match',
'If-Modified-Since',
'If-None-Match',
'If-Range',
'If-Unmodified-Since',
'Keep-Alive',
'Last-Modified',
'Link',
'Location',
'Max-Forwards',
'Origin',
'Permissions-Policy',
'Pragma',
'Proxy-Authenticate',
'Proxy-Authorization',
'RTT',
'Range',
'Referer',
'Referrer-Policy',
'Refresh',
'Retry-After',
'Sec-WebSocket-Accept',
'Sec-WebSocket-Extensions',
'Sec-WebSocket-Key',
'Sec-WebSocket-Protocol',
'Sec-WebSocket-Version',
'Server',
'Server-Timing',
'Service-Worker-Allowed',
'Service-Worker-Navigation-Preload',
'Set-Cookie',
'SourceMap',
'Strict-Transport-Security',
'Supports-Loading-Mode',
'TE',
'Timing-Allow-Origin',
'Trailer',
'Transfer-Encoding',
'Upgrade',
'Upgrade-Insecure-Requests',
'User-Agent',
'Vary',
'Via',
'WWW-Authenticate',
'X-Content-Type-Options',
'X-DNS-Prefetch-Control',
'X-Frame-Options',
'X-Permitted-Cross-Domain-Policies',
'X-Powered-By',
'X-Requested-With',
'X-XSS-Protection'
]
for (let i = 0; i < wellknownHeaderNames.length; ++i) {
const key = wellknownHeaderNames[i]
const lowerCasedKey = key.toLowerCase()
headerNameLowerCasedRecord[key] = headerNameLowerCasedRecord[lowerCasedKey] =
lowerCasedKey
}
// Note: object prototypes should not be able to be referenced. e.g. `Object#hasOwnProperty`.
Object.setPrototypeOf(headerNameLowerCasedRecord, null)
module.exports = {
wellknownHeaderNames,
headerNameLowerCasedRecord
}
/***/ }),
/***/ 8045:
@ -12578,6 +12704,7 @@ const { InvalidArgumentError } = __nccwpck_require__(8045)
const { Blob } = __nccwpck_require__(4300)
const nodeUtil = __nccwpck_require__(3837)
const { stringify } = __nccwpck_require__(3477)
const { headerNameLowerCasedRecord } = __nccwpck_require__(4462)
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(v => Number(v))
@ -12787,6 +12914,15 @@ function parseKeepAliveTimeout (val) {
return m ? parseInt(m[1], 10) * 1000 : null
}
/**
* Retrieves a header name and returns its lowercase value.
* @param {string | Buffer} value Header name
* @returns {string}
*/
function headerNameToString (value) {
return headerNameLowerCasedRecord[value] || value.toLowerCase()
}
function parseHeaders (headers, obj = {}) {
// For H2 support
if (!Array.isArray(headers)) return headers
@ -13058,6 +13194,7 @@ module.exports = {
isIterable,
isAsyncIterable,
isDestroyed,
headerNameToString,
parseRawHeaders,
parseHeaders,
parseKeepAliveTimeout,
@ -19705,14 +19842,18 @@ const { isBlobLike, toUSVString, ReadableStreamFrom } = __nccwpck_require__(3983
const assert = __nccwpck_require__(9491)
const { isUint8Array } = __nccwpck_require__(9830)
let supportedHashes = []
// https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
/** @type {import('crypto')|undefined} */
let crypto
try {
crypto = __nccwpck_require__(6113)
const possibleRelevantHashes = ['sha256', 'sha384', 'sha512']
supportedHashes = crypto.getHashes().filter((hash) => possibleRelevantHashes.includes(hash))
/* c8 ignore next 3 */
} catch {
}
function responseURL (response) {
@ -20240,66 +20381,56 @@ function bytesMatch (bytes, metadataList) {
return true
}
// 3. If parsedMetadata is the empty set, return true.
// 3. If response is not eligible for integrity validation, return false.
// TODO
// 4. If parsedMetadata is the empty set, return true.
if (parsedMetadata.length === 0) {
return true
}
// 4. Let metadata be the result of getting the strongest
// 5. Let metadata be the result of getting the strongest
// metadata from parsedMetadata.
const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo))
// get the strongest algorithm
const strongest = list[0].algo
// get all entries that use the strongest algorithm; ignore weaker
const metadata = list.filter((item) => item.algo === strongest)
const strongest = getStrongestMetadata(parsedMetadata)
const metadata = filterMetadataListByAlgorithm(parsedMetadata, strongest)
// 5. For each item in metadata:
// 6. For each item in metadata:
for (const item of metadata) {
// 1. Let algorithm be the alg component of item.
const algorithm = item.algo
// 2. Let expectedValue be the val component of item.
let expectedValue = item.hash
const expectedValue = item.hash
// See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e
// "be liberal with padding". This is annoying, and it's not even in the spec.
if (expectedValue.endsWith('==')) {
expectedValue = expectedValue.slice(0, -2)
}
// 3. Let actualValue be the result of applying algorithm to bytes.
let actualValue = crypto.createHash(algorithm).update(bytes).digest('base64')
if (actualValue.endsWith('==')) {
if (actualValue[actualValue.length - 1] === '=') {
if (actualValue[actualValue.length - 2] === '=') {
actualValue = actualValue.slice(0, -2)
} else {
actualValue = actualValue.slice(0, -1)
}
}
// 4. If actualValue is a case-sensitive match for expectedValue,
// return true.
if (actualValue === expectedValue) {
return true
}
let actualBase64URL = crypto.createHash(algorithm).update(bytes).digest('base64url')
if (actualBase64URL.endsWith('==')) {
actualBase64URL = actualBase64URL.slice(0, -2)
}
if (actualBase64URL === expectedValue) {
if (compareBase64Mixed(actualValue, expectedValue)) {
return true
}
}
// 6. Return false.
// 7. Return false.
return false
}
// https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options
// https://www.w3.org/TR/CSP2/#source-list-syntax
// https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1
const parseHashWithOptions = /((?<algo>sha256|sha384|sha512)-(?<hash>[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i
const parseHashWithOptions = /(?<algo>sha256|sha384|sha512)-((?<hash>[A-Za-z0-9+/]+|[A-Za-z0-9_-]+)={0,2}(?:\s|$)( +[!-~]*)?)?/i
/**
* @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata
@ -20313,8 +20444,6 @@ function parseMetadata (metadata) {
// 2. Let empty be equal to true.
let empty = true
const supportedHashes = crypto.getHashes()
// 3. For each token returned by splitting metadata on spaces:
for (const token of metadata.split(' ')) {
// 1. Set empty to false.
@ -20324,7 +20453,11 @@ function parseMetadata (metadata) {
const parsedToken = parseHashWithOptions.exec(token)
// 3. If token does not parse, continue to the next token.
if (parsedToken === null || parsedToken.groups === undefined) {
if (
parsedToken === null ||
parsedToken.groups === undefined ||
parsedToken.groups.algo === undefined
) {
// Note: Chromium blocks the request at this point, but Firefox
// gives a warning that an invalid integrity was given. The
// correct behavior is to ignore these, and subsequently not
@ -20333,11 +20466,11 @@ function parseMetadata (metadata) {
}
// 4. Let algorithm be the hash-algo component of token.
const algorithm = parsedToken.groups.algo
const algorithm = parsedToken.groups.algo.toLowerCase()
// 5. If algorithm is a hash function recognized by the user
// agent, add the parsed token to result.
if (supportedHashes.includes(algorithm.toLowerCase())) {
if (supportedHashes.includes(algorithm)) {
result.push(parsedToken.groups)
}
}
@ -20350,6 +20483,82 @@ function parseMetadata (metadata) {
return result
}
/**
* @param {{ algo: 'sha256' | 'sha384' | 'sha512' }[]} metadataList
*/
function getStrongestMetadata (metadataList) {
// Let algorithm be the algo component of the first item in metadataList.
// Can be sha256
let algorithm = metadataList[0].algo
// If the algorithm is sha512, then it is the strongest
// and we can return immediately
if (algorithm[3] === '5') {
return algorithm
}
for (let i = 1; i < metadataList.length; ++i) {
const metadata = metadataList[i]
// If the algorithm is sha512, then it is the strongest
// and we can break the loop immediately
if (metadata.algo[3] === '5') {
algorithm = 'sha512'
break
// If the algorithm is sha384, then a potential sha256 or sha384 is ignored
} else if (algorithm[3] === '3') {
continue
// algorithm is sha256, check if algorithm is sha384 and if so, set it as
// the strongest
} else if (metadata.algo[3] === '3') {
algorithm = 'sha384'
}
}
return algorithm
}
function filterMetadataListByAlgorithm (metadataList, algorithm) {
if (metadataList.length === 1) {
return metadataList
}
let pos = 0
for (let i = 0; i < metadataList.length; ++i) {
if (metadataList[i].algo === algorithm) {
metadataList[pos++] = metadataList[i]
}
}
metadataList.length = pos
return metadataList
}
/**
* Compares two base64 strings, allowing for base64url
* in the second string.
*
* @param {string} actualValue always base64
* @param {string} expectedValue base64 or base64url
* @returns {boolean}
*/
function compareBase64Mixed (actualValue, expectedValue) {
if (actualValue.length !== expectedValue.length) {
return false
}
for (let i = 0; i < actualValue.length; ++i) {
if (actualValue[i] !== expectedValue[i]) {
if (
(actualValue[i] === '+' && expectedValue[i] === '-') ||
(actualValue[i] === '/' && expectedValue[i] === '_')
) {
continue
}
return false
}
}
return true
}
// https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
function tryUpgradeRequestToAPotentiallyTrustworthyURL (request) {
// TODO
@ -20765,7 +20974,8 @@ module.exports = {
urlHasHttpsScheme,
urlIsHttpHttpsScheme,
readAllBytes,
normalizeMethodRecord
normalizeMethodRecord,
parseMetadata
}
@ -22852,12 +23062,17 @@ function parseLocation (statusCode, headers) {
// https://tools.ietf.org/html/rfc7231#section-6.4.4
function shouldRemoveHeader (header, removeContent, unknownOrigin) {
return (
(header.length === 4 && header.toString().toLowerCase() === 'host') ||
(removeContent && header.toString().toLowerCase().indexOf('content-') === 0) ||
(unknownOrigin && header.length === 13 && header.toString().toLowerCase() === 'authorization') ||
(unknownOrigin && header.length === 6 && header.toString().toLowerCase() === 'cookie')
)
if (header.length === 4) {
return util.headerNameToString(header) === 'host'
}
if (removeContent && util.headerNameToString(header).startsWith('content-')) {
return true
}
if (unknownOrigin && (header.length === 13 || header.length === 6 || header.length === 19)) {
const name = util.headerNameToString(header)
return name === 'authorization' || name === 'cookie' || name === 'proxy-authorization'
}
return false
}
// https://tools.ietf.org/html/rfc7231#section-6.4
@ -27384,13 +27599,18 @@ module.exports = {
* console.log(listener.contents);
*/
class OutputListener {
constructor () {
constructor (streamWriter) {
this._buff = [];
this._streamWriter = streamWriter;
}
get listener () {
const listen = function listen (data) {
this._buff.push(data);
if (this._streamWriter) {
this._streamWriter.write(data);
}
};
return listen.bind(this);
}
@ -27731,9 +27951,9 @@ async function checkTerraform () {
// This will fail if Terraform isn't found, which is what we want
await checkTerraform();
// Create listeners to receive output (in memory) as well
const stdout = new OutputListener();
const stderr = new OutputListener();
// Create listeners to receive output (in memory)
const stdout = new OutputListener(process.stdout);
const stderr = new OutputListener(process.stderr);
const listeners = {
stdout: stdout.listener,
stderr: stderr.listener
@ -27748,10 +27968,6 @@ async function checkTerraform () {
};
const exitCode = await exec(pathToCLI, args, options);
// Pass-through stdout/err as `exec` won't due to `silent: true` option
process.stdout.write(stdout.contents);
process.stderr.write(stderr.contents);
// Set outputs, result, exitcode, and stderr
core.setOutput('stdout', stdout.contents);
core.setOutput('stderr', stderr.contents);

View file

@ -7,6 +7,7 @@
const fs = require('fs').promises;
const os = require('os');
const path = require('path');
const semver = require('semver');
// External
const core = require('@actions/core');
@ -165,7 +166,15 @@ async function run () {
core.debug(`Finding releases for Terraform version ${version}`);
const release = await releases.getRelease('terraform', version, 'GitHub Action: Setup Terraform');
const platform = mapOS(osPlatform);
const arch = mapArch(osArch);
let arch = mapArch(osArch);
// Terraform was not available for darwin/arm64 until 1.0.2, however macOS
// runners can emulate darwin/amd64.
if (platform === 'darwin' && arch === 'arm64' && semver.valid(release.version) && semver.lt(release.version, '1.0.2')) {
core.warning('Terraform is not available for darwin/arm64 until version 1.0.2. Falling back to darwin/amd64.');
arch = 'amd64';
}
core.debug(`Getting build for Terraform version ${release.version}: ${platform} ${arch}`);
const build = release.getBuild(platform, arch);
if (!build) {

319
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "setup-terraform",
"version": "3.0.0",
"version": "3.1.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "setup-terraform",
"version": "3.0.0",
"version": "3.1.1",
"license": "MPL-2.0",
"dependencies": {
"@actions/core": "^1.10.1",
@ -14,7 +14,8 @@
"@actions/github": "^6.0.0",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.1",
"@hashicorp/js-releases": "^1.7.2"
"@hashicorp/js-releases": "^1.7.2",
"semver": "^7.6.2"
},
"devDependencies": {
"@vercel/ncc": "^0.38.1",
@ -95,6 +96,14 @@
"uuid": "^3.3.2"
}
},
"node_modules/@actions/tool-cache/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@ampproject/remapping": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
@ -237,6 +246,15 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
"node_modules/@babel/core/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/generator": {
"version": "7.23.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
@ -277,6 +295,15 @@
"yallist": "^3.0.2"
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@ -872,20 +899,6 @@
"yauzl": "^2.10.0"
}
},
"node_modules/@hashicorp/js-releases/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.11",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
@ -1895,6 +1908,15 @@
"node": ">=8"
}
},
"node_modules/babel-plugin-istanbul/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/babel-plugin-jest-hoist": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
@ -2051,21 +2073,6 @@
"semver": "^7.0.0"
}
},
"node_modules/builtins/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@ -2800,6 +2807,15 @@
"node": ">=0.10.0"
}
},
"node_modules/eslint-plugin-import/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/eslint-plugin-n": {
"version": "15.7.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz",
@ -2825,21 +2841,6 @@
"eslint": ">=7.0.0"
}
},
"node_modules/eslint-plugin-n/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/eslint-plugin-promise": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz",
@ -2911,6 +2912,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/eslint-plugin-react/node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/eslint-scope": {
"version": "7.2.2",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
@ -3294,9 +3304,9 @@
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
@ -4143,21 +4153,6 @@
"node": ">=10"
}
},
"node_modules/istanbul-lib-instrument/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/istanbul-lib-report": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
@ -4716,21 +4711,6 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/jest-snapshot/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/jest-util": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
@ -5043,17 +5023,6 @@
"loose-envify": "cli.js"
}
},
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/make-dir": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
@ -5069,21 +5038,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/make-dir/node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/makeerror": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
@ -5962,11 +5916,14 @@
}
},
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/shebang-command": {
@ -6459,9 +6416,9 @@
}
},
"node_modules/undici": {
"version": "5.28.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
@ -6695,11 +6652,6 @@
"node": ">=10"
}
},
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@ -6816,6 +6768,13 @@
"@actions/io": "^1.1.1",
"semver": "^6.1.0",
"uuid": "^3.3.2"
},
"dependencies": {
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
}
}
},
"@ampproject/remapping": {
@ -6930,6 +6889,12 @@
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
},
@ -6967,6 +6932,12 @@
"yallist": "^3.0.2"
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
},
"yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@ -7407,16 +7378,6 @@
"openpgp": "^5.5.0",
"semver": "^7.3.5",
"yauzl": "^2.10.0"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"@humanwhocodes/config-array": {
@ -8218,6 +8179,12 @@
"istanbul-lib-coverage": "^3.2.0",
"semver": "^6.3.0"
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
},
@ -8337,17 +8304,6 @@
"dev": true,
"requires": {
"semver": "^7.0.0"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"call-bind": {
@ -8943,6 +8899,12 @@
"requires": {
"esutils": "^2.0.2"
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
},
@ -8960,17 +8922,6 @@
"minimatch": "^3.1.2",
"resolve": "^1.22.1",
"semver": "^7.3.8"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"eslint-plugin-promise": {
@ -9023,6 +8974,12 @@
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
},
@ -9232,9 +9189,9 @@
"dev": true
},
"follow-redirects": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
"version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
},
"for-each": {
"version": "0.3.3",
@ -9805,17 +9762,6 @@
"@istanbuljs/schema": "^0.1.2",
"istanbul-lib-coverage": "^3.2.0",
"semver": "^7.5.4"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"istanbul-lib-report": {
@ -10244,17 +10190,6 @@
"natural-compare": "^1.4.0",
"pretty-format": "^29.7.0",
"semver": "^7.5.3"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"jest-util": {
@ -10506,14 +10441,6 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"make-dir": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
@ -10521,17 +10448,6 @@
"dev": true,
"requires": {
"semver": "^7.5.3"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
}
}
}
},
"makeerror": {
@ -11152,9 +11068,9 @@
}
},
"semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w=="
},
"shebang-command": {
"version": "2.0.0",
@ -11516,9 +11432,9 @@
}
},
"undici": {
"version": "5.28.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
"version": "5.28.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
"integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
"requires": {
"@fastify/busboy": "^2.0.0"
}
@ -11685,11 +11601,6 @@
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",

View file

@ -1,6 +1,6 @@
{
"name": "setup-terraform",
"version": "3.0.0",
"version": "3.1.1",
"description": "Setup Terraform CLI for GitHub Actions",
"license": "MPL-2.0",
"publisher": "hashicorp",
@ -23,7 +23,8 @@
"@actions/github": "^6.0.0",
"@actions/io": "^1.1.3",
"@actions/tool-cache": "^2.0.1",
"@hashicorp/js-releases": "^1.7.2"
"@hashicorp/js-releases": "^1.7.2",
"semver": "^7.6.2"
},
"devDependencies": {
"@vercel/ncc": "^0.38.1",

View file

@ -20,13 +20,18 @@
* console.log(listener.contents);
*/
class OutputListener {
constructor () {
constructor (streamWriter) {
this._buff = [];
this._streamWriter = streamWriter;
}
get listener () {
const listen = function listen (data) {
this._buff.push(data);
if (this._streamWriter) {
this._streamWriter.write(data);
}
};
return listen.bind(this);
}

View file

@ -21,9 +21,9 @@ async function checkTerraform () {
// This will fail if Terraform isn't found, which is what we want
await checkTerraform();
// Create listeners to receive output (in memory) as well
const stdout = new OutputListener();
const stderr = new OutputListener();
// Create listeners to receive output (in memory)
const stdout = new OutputListener(process.stdout);
const stderr = new OutputListener(process.stderr);
const listeners = {
stdout: stdout.listener,
stderr: stderr.listener
@ -38,10 +38,6 @@ async function checkTerraform () {
};
const exitCode = await exec(pathToCLI, args, options);
// Pass-through stdout/err as `exec` won't due to `silent: true` option
process.stdout.write(stdout.contents);
process.stderr.write(stderr.contents);
// Set outputs, result, exitcode, and stderr
core.setOutput('stdout', stdout.contents);
core.setOutput('stderr', stderr.contents);

View file

@ -6,12 +6,31 @@
const OutputListener = require('../lib/output-listener');
describe('output-listener', () => {
it('receives and exposes data', () => {
it('receives and buffers data to .contents', () => {
const listener = new OutputListener();
const listen = listener.listener;
listen(Buffer.from('foo'));
listen(Buffer.from('bar'));
listen(Buffer.from('baz'));
expect(listener.contents).toEqual('foobarbaz');
});
it('receives and writes data to stream immediately', () => {
const mockWrite = jest.fn();
const listener = new OutputListener({ write: mockWrite });
const listen = listener.listener;
listen(Buffer.from('first write'));
expect(mockWrite.mock.lastCall[0]).toStrictEqual(Buffer.from('first write'));
listen(Buffer.from('second write'));
expect(mockWrite.mock.lastCall[0]).toStrictEqual(Buffer.from('second write'));
listen(Buffer.from('third write'));
expect(mockWrite.mock.lastCall[0]).toStrictEqual(Buffer.from('third write'));
expect(mockWrite).toBeCalledTimes(3);
});
});