Cleanup github workflows (#2903)

Signed-off-by: Christian Mesh <christianmesh1@gmail.com>
This commit is contained in:
Christian Mesh
2025-06-11 07:15:07 -04:00
committed by GitHub
parent 9b6a8fae60
commit 52700e677e
20 changed files with 73 additions and 1175 deletions

View File

@@ -1,28 +0,0 @@
# Copyright (c) The OpenTofu Authors
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2023 HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
name: 'Determine Go Toolchain Version'
description: 'Uses the .go-version file to determine which Go toolchain to use for any Go-related actions downstream.'
outputs:
version:
description: "Go toolchain version"
value: ${{ steps.go.outputs.version }}
runs:
using: "composite"
steps:
# We use goenv to make sure we're always using the same Go version we'd
# use for releases, as recorded in the .go-version file.
- name: "Determine Go version"
id: go
shell: bash
# We use .go-version as our source of truth for current Go
# version, because "goenv" can react to it automatically.
# However, we don't actually use goenv for our automated
# steps in GitHub Actions, because it's primarily for
# interactive use in shells and makes things unnecessarily
# complex for automation.
run: |
echo "Building with Go $(cat .go-version)"
echo "version=$(cat .go-version)" >> "$GITHUB_OUTPUT"

View File

@@ -1,21 +0,0 @@
# Backport Merged Pull Request
## Overview
This feature automates the process of creating pull requests for backporting merged changes to a designated target branch.
### How to Use
1. **Label Your Pull Request**: To initiate a backport, simply add a label to your pull request in the format `backport <target_branch>`, where `<target_branch>` is the branch you want to backport changes to (eg. `backport v1.x`). The backport labels can be added to both open and closed pull requests.
2. **Automatic Backport Pull Request Creation**: After the pull request is merged and closed, or if the backport label is added to an already closed pull request, backport GitHub Action will execute the `.github/scripts/backport/main.sh` script, which will automatically create a new pull request with the changes backported to the specified `<target_branch>`. A comment linking to the new Backport Pull Request will be added to the original pull request for easy navigation.
### Handling Merge Conflicts
- In some cases, the automatic backport process may encounter merge conflicts that cannot be resolved automatically.
- If this occurs, a comment will be posted on the original pull request indicating the conflict and providing the commit SHA causing the issue.
- When a merge conflict arises, you'll need to manually backport your changes to the target branch and resolve any conflicts as part of the manual pull request process. [Please see the contributing guide for more details](https://github.com/opentofu/opentofu/blob/main/CONTRIBUTING.md#backporting)
### Note
- **Use Clear Labels**: Ensure the `backport <target_branch>` label is correctly formatted.

View File

@@ -1,237 +0,0 @@
# Copyright (c) The OpenTofu Authors
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2023 HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
#!/bin/bash
set -eou pipefail
# Color codes for logs
COLOR_RESET="\033[0m"
COLOR_GREEN="\033[32m"
COLOR_RED="\033[31m"
# This function outputs error logs.
log_error() {
if [ -z "$1" ]; then
echo -e "${COLOR_RED}Error: No error message provided.${COLOR_RESET}" >&2
exit 1
fi
echo -e "${COLOR_RED}Error: $1${COLOR_RESET}" >&2
exit 1
}
# This function outputs info logs.
log_info() {
if [ -z "$1" ]; then
echo -e "${COLOR_RED}Error: No info message provided.${COLOR_RESET}"
return
fi
echo -e "${COLOR_GREEN}$1${COLOR_RESET}"
}
# This function sets up the committer identity.
setup_committer_identity() {
log_info "Setting up committer identity..."
if ! git config user.email "noreply@github.com"; then
log_error "Failed to set email."
fi
if ! git config user.name "GitHub Actions"; then
log_error "Failed to set a username."
fi
log_info "Successfully set the committer identity."
}
# This function checks the GITHUB_TOKEN, gh auth and environment variables are set or not.
validate_github_auth_and_env_vars() {
# Check if GitHub token is set
log_info "Checking if GITHUB_TOKEN is set..."
if [ -z "$GITHUB_TOKEN" ]; then
log_error "GitHub token is not available. Please ensure a secret named 'GITHUB_TOKEN' is defined."
fi
log_info "GITHUB_TOKEN is set successfully."
log_info "Checking if required environment variables are set..."
if [ -z "$OWNER" ] || [ -z "$REPO" ] || [ -z "$PR_NUMBER" ] || [ -z "$ISSUE_NUMBER" ] || [ -z "$HEAD_BRANCH" ]; then
log_error "One or more required environment variables (OWNER, REPO, PR_NUMBER, ISSUE_NUMBER, HEAD_BRANCH) are not set."
fi
log_info "All the environment variables are set successfully."
# Check if gh is logged in
log_info "Checking if 'gh' auth is set..."
if ! gh auth status >/dev/null 2>&1; then
log_error "Authentication check for 'gh' failed."
fi
log_info "'gh' authentication is set up successfully."
}
# This function cherry-picks the commits onto the new backport branch.
cherry_pick_commits() {
# Get the commit SHAs associated with the pull request
log_info "Fetching commit SHAs from the pull request..."
if ! commit_shas=$(gh api "/repos/$OWNER/$REPO/pulls/$PR_NUMBER/commits" --jq '.[].sha'); then
log_error "Failed to fetch commit SHAs from the pull request #${PR_NUMBER}."
fi
# Check if commit_shas is empty
log_info "Checking if any commit SHAs were fetched..."
if [ -z "$commit_shas" ]; then
log_error "No commit SHAs were found in the pull request #${PR_NUMBER}."
fi
log_info "Commit SHAs were successfully fetched."
while IFS= read -r commit_sha; do
log_info "Fetching the commit id: '${commit_sha}'..."
if ! git fetch origin "$commit_sha"; then
log_error "Failed to fetch the commit id: '${commit_sha}'"
fi
log_info "Successfully fetched the commit id: '${commit_sha}'"
log_info "Cherry-picking the commit id: '${commit_sha}'..."
if git cherry-pick "$commit_sha" ; then
log_info "Successfully cherry-picked the commit id: '${commit_sha}'"
else
# Add a failure comment to the pull request
failureComment="Error: Cherry-pick commit '$commit_sha' failed during the backport process to '$1'. Please resolve any conflicts and manually apply the changes."
if ! gh pr comment "$PR_NUMBER" --body "$failureComment"; then
log_error "Failed to add failure comment to the pull request #${PR_NUMBER}."
fi
log_info "Successfully added failure comment to the pull request."
log_error "Failed to cherry-pick commit '${commit_sha}'. Added failure comment to the pull request."
fi
done <<< "$commit_shas"
return 0
}
# This function creates the pull request.
create_pull_request() {
local target_branch=$1
local backport_branch=$2
title="Backport PR #$ISSUE_NUMBER: '$HEAD_BRANCH' to '$target_branch'"
body="This pull request backports changes from branch '$HEAD_BRANCH' to branch '$target_branch'."
if ! url=$(gh pr create --title "$title" --body "$body" --base "$target_branch" --head "$backport_branch"); then
return 1
fi
echo "${url}"
}
# This function performs all the operations required to backport a pull request to a target branch.
backport_changes() {
local target_branch=$1
local backport_branch=$2
# Fetch and checkout the target branch.
log_info "Fetching branch '$target_branch'..."
if ! git fetch origin "$target_branch"; then
log_error "Failed to fetch branch: '$target_branch'."
fi
log_info "Successfully fetched branch: '$target_branch'."
log_info "Checking out branch '$target_branch'..."
if ! git checkout "$target_branch"; then
log_error "Failed to checkout branch: '$target_branch'"
fi
log_info "Successfully checked out branch: '$target_branch'."
# Check whether the new backport branch already exists. If it does, delete the branch to remove any unnecessary changes.
log_info "Checking if new backport branch already exists '$backport_branch'..."
if git ls-remote --exit-code --heads origin "$backport_branch" >/dev/null 2>&1; then
if git push origin --delete "$backport_branch" >/dev/null 2>&1; then
log_info "Successfully deleted existing backport branch: '$backport_branch'"
else
log_error "Failed to delete existing backport branch: '$backport_branch'"
fi
fi
# Checking out new backport branch
log_info "Checking out new backport branch '$backport_branch'..."
if ! git checkout -b "$backport_branch"; then
log_error "Failed to create new backport branch: '$backport_branch'"
fi
log_info "Successfully checked out new backport branch: '$backport_branch'."
# Cherry-pick commits
log_info "Starting the cherry-pick process for the pull request #${PR_NUMBER}..."
if ! cherry_pick_commits "$target_branch"; then
log_error "Failed to cherry-pick commits for the pull request."
fi
log_info "Cherry-pick completed successfully for the pull request #${PR_NUMBER}."
# Push final changes to the backport branch
log_info "Pushing changes to the branch: '$backport_branch'..."
if ! git push origin "$backport_branch"; then
log_error "Failed to push changes to the branch: '$backport_branch'."
fi
log_info "Successfully pushed changes to the branch: '$backport_branch'"
# Create the pull request
log_info "Creating pull request between '$target_branch' and '$backport_branch'..."
if ! pull_request_url=$(create_pull_request "$target_branch" "$backport_branch"); then
log_error "Failed to create the pull request."
fi
log_info "Pull request created successfully. You can view the pull request at: ${pull_request_url}."
# Add comment to the pull request
comment="This pull request has been successfully backported. Link to the new pull request: ${pull_request_url}."
log_info "Adding a comment to the original pull request #${PR_NUMBER} created between '$target_branch' and '$backport_branch'..."
if ! gh pr comment "$PR_NUMBER" --body "$comment"; then
log_error "Failed to add a comment to the original pull request #${PR_NUMBER} created between '$target_branch' and '$backport_branch'."
fi
log_info "Successfully added a comment to the original pull request #${PR_NUMBER} created between '$target_branch' and '$backport_branch'."
}
main() {
log_info "Starting the process of creating pull requests for backporting merged changes to a designated target branch."
# Set up committer identity
setup_committer_identity
# Validate GitHub token, gh auth, and environment variables
validate_github_auth_and_env_vars
# Retrieve the list of branches for backporting the pull request changes.
log_info "Starting the process of identifying a list of branches where pull request changes will be backported to... "
target_branches=()
readarray -t labelArray < <(echo "$LABELS" | jq -r '.[]')
for label in "${labelArray[@]}"; do
if [[ $label == "backport"* ]]; then
target_branches+=("${label#backport }")
fi
done
log_info "Validate all the target branches to which the pull request changes will be backported..."
if [ ${#target_branches[@]} -eq 0 ]; then
log_info "No target branches found. The backport label is not found in any of the labels on the pull request. Skipping the backport process."
exit 0
fi
log_info "Successfully found the following target branches: ${target_branches[*]}"
# Iterate over each target branch and attempt to backport the changes
for branch in "${target_branches[@]}"; do
(
new_backport_branch="backport/$branch/$ISSUE_NUMBER"
log_info "Checking if pull request already exists between the branch '$branch' and '$new_backport_branch'."
pull_request_list=$(gh pr list --base="$branch" --head="$new_backport_branch" --json number,title)
# If a pull request already exists between branch and new_backport_branch,
# then skip backporting the pull request changes.
if [ "$(echo "$pull_request_list" | jq length)" -eq 0 ]; then
log_info "Starting the backport process for branch: $branch."
if ! backport_changes "$branch" "$new_backport_branch"; then
log_error "Failed to backport changes to the branch: $branch."
fi
log_info "Successfully backported the pull request changes to the branch '$branch'."
else
log_info "Pull requests already exist between the branch '$branch' and '$new_backport_branch'. Skipping backport for '$branch'"
fi
)
done
log_info "Successfully, completed the backporting for the pull request #${PR_NUMBER}."
}
main

View File

@@ -1,182 +0,0 @@
# Manual Test Cases #
## Successful Test Cases ##
**Test Case 1**: Valid backport pull request with single backport label.
**Objective**: Verify that the script backports a valid pull request without issues after adding a backport label.
**Steps**:
- Add a backport label to your pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x).
- Ensure that the pull request is fully approved and merged into the main branch.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Info logs confirming the successful backporting process are displayed, indicating the completion of backporting to *<target_branch>*.
- For eg: Successfully backported the pull request changes to the branch *<target_branch>*.
- The `Backport Merged Pull Request` workflow completes without encountering any errors.
- A new pull request is created successfully, incorporating only the changes from the labeled pull request that need to be backported.
- Format: Backport PR *#<pull_request_number>*: *<source_branch>* to *<target_branch>*.
- A comment is added to the original pull request, indicating the completion of the backporting process.
---
**Test Case 2**: Valid backport pull request with multiple backport label.
**Objective**: Verify that the script backports a valid pull request without issues after adding multiple backport labels.
**Steps**:
- Add multiple backport labels to your pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x)
- Ensure that the pull request is fully approved and merged into the main branch.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Info log about the successful backporting to each *<target_branch>* can be found.
- For eg: Successfully backported the pull request changes to the branch *<target_branch>*.
- Info logs confirming the successful backporting process to all target branches are displayed, indicating the completion of backporting to *<target_branch>*.
Successfully, completed the backporting for the pull request *#<pull_request_number>*.
- The `Backport Merged Pull Request` workflow completes without encountering any errors.
- A new pull request is created successfully for all the target branches, incorporating only the changes from the labeled pull request that need to be backported.
- Format: Backport PR *#<pull_request_number>*: *<source_branch>* to *<target_branch>*.
- A comment is added to the original pull request, indicating the completion of the backporting process.
---
**Test Case 3**: No backport labels provided.
**Objective**: Verify that the script doesnt fail when no backport label is provided.
**Steps**:
- Ensure that the pull request is fully approved and merged into the main branch without adding any backport labels.
- Backport labels should have a `backport` prefix followed by the *<target_branch>*.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- `Run custom bash script for backporting` step should be skipped in the workflow.
- The script */backport/main.sh* should be skipped.
- The `Backport Merged Pull Request` workflow completes without encountering any errors.
---
**Test Case 4**: Pull request already exists.
**Objective**: Verify that the script successfully shows the info log that pull request already exists between new backport branch and target branch where original pull request changes will be backported to.
**Steps**:
- The pull request should already exists between target branch and new backport branch.
- Add a backport label to your original pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x).
- Ensure that the pull request is fully approved and merged into the main branch.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Info log mentioning details about skipping backport process can be found.
- For eg: Pull requests already exist between the branch *<source_branch>* and *<target_branch>*. Skipping backport for *<target_branch>*.
- The `Backport Merged Pull Request` workflow completes without encountering any errors.
## Failure Test Cases ##
**Test Case 1**: Merge conflict while cherry picking.
**Objective**: Verify the script add a comment to the original pull request when merge conflict happens while cherry picking.
**Steps**:
- Add multiple backport labels to your pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x)
- Ensure that the pull request is fully approved and merged into the main branch.
**Error log**: Failed to cherry-pick commit <commit_id>. Added failure comment to the pull request.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Error logs detailing the backport failure are generated.
- Backport Merged Pull Request workflow failed with errors.
- A comment is added to the original pull request, indicating the completion of the backporting process.
- Error: Cherry-pick commit <commit_id> failed during the backport process to *<target_branch>*. Please resolve any conflicts and manually apply the changes.
---
**Test Case 2**: Unable to fetch commit id.
**Objective**: Verify that the script failed when commit id was not successfully fetched and proper error log should be generated to identify the issue.
**Steps**:
- Add multiple backport labels to your pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x).
- Ensure that the pull request is fully approved and merged into the main branch.
**Error log**: Failed to fetch the commit id: '<commit_id>.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Error log mentioning details about backport failure can be found.
- Backport Merged Pull Request workflow failed with errors.
- No comments will be added.
---
**Test Case 3**: Unable to fetch target branch.
**Objective**: Verify that the script failed when the target branch was not found.
**Steps**:
- Add a backport label to your pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x)
- Ensure that the pull request is fully approved and merged into the main branch.
**Error log**: Failed to fetch branch: '*<target_branch>*.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Error log mentioning details about backport failure can be found.
- Backport Merged Pull Request workflow failed with errors.
- No comments will be added.
---
**Test Case 4**: Failed to create the pull request.
**Objective**: Verify that the script failed when the pull request was not created.
**Steps**:
- Add a backport label to your pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x)
- Ensure that the pull request is fully approved and merged into the main branch.
**Error log**: Failed to create the pull request.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Error log mentioning details about backport failure can be found.
- Backport Merged Pull Request workflow failed with errors.
- No comments will be added.
---
**Test Case 5**: Failed to add comment to the original pull request.
**Objective**: Verify that the script failed when the comment was not added to the original pull request.
**Steps**:
- Add a backport label to your pull request.
- Format backport *<target_branch>*, where *<target_branch>* is the branch you want to backport changes to (eg. backport v1.x)
- Ensure that the pull request is fully approved and merged into the main branch.
**Error log**: Failed to add a comment to the original pull request *#<pull_request_number>* created between *<target_branch>* and <backport_branch>.
**Expected Results**:
- The `Backport Merged Pull Request` workflow initiates automatically upon the addition of the backport label.
- The script *backport/main.sh* begins backporting the changes from the labeled pull request to the specified target branch (*<target_branch>*).
- Error log mentioning details about backport failure can be found.
- Backport Merged Pull Request workflow failed with errors.
- No comments will be added.

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) The OpenTofu Authors
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2023 HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
set -uo pipefail
if [[ $arch == 'arm' || $arch == 'arm64' ]]
then
export DIR=$(mktemp -d)
unzip -d $DIR "${e2e_cache_path}/tofu-e2etest_${os}_${arch}.zip"
unzip -d $DIR "./tofu_${version}_${os}_${arch}.zip"
sudo chmod +x $DIR/e2etest
docker run --platform=linux/arm64 -v $DIR:/src -w /src arm64v8/alpine ./e2etest -test.v
else
unzip "${e2e_cache_path}/tofu-e2etest_${os}_${arch}.zip"
unzip "./tofu_${version}_${os}_${arch}.zip"
TF_ACC=1 ./e2etest -test.v
fi

View File

@@ -1,43 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) The OpenTofu Authors
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2023 HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
set -uo pipefail
# Trim the "v" prefix, if any.
VERSION="${RAW_VERSION#v}"
# Split off the build metadata part, if any
# (we won't actually include it in our final version, and handle it only for
# completeness against semver syntax.)
IFS='+' read -ra VERSION BUILD_META <<< "$VERSION"
# Separate out the prerelease part, if any
# (version.go expects it to be in a separate variable)
IFS='-' read -r BASE_VERSION PRERELEASE <<< "$VERSION"
EXPERIMENTS_ENABLED=0
if [[ "$PRERELEASE" == alpha* ]]; then
EXPERIMENTS_ENABLED=1
fi
if [[ "$PRERELEASE" == dev* ]]; then
EXPERIMENTS_ENABLED=1
fi
LDFLAGS="-w -s"
if [[ "$EXPERIMENTS_ENABLED" == 1 ]]; then
LDFLAGS="${LDFLAGS} -X 'main.experimentsAllowed=yes'"
fi
LDFLAGS="${LDFLAGS} -X 'github.com/opentofu/opentofu/version.dev=no'"
echo "Building OpenTofu CLI ${VERSION}"
if [[ "$EXPERIMENTS_ENABLED" == 1 ]]; then
echo "This build allows use of experimental features"
fi
echo "product-version=${VERSION}" | tee -a "${GITHUB_OUTPUT}"
echo "product-version-base=${BASE_VERSION}" | tee -a "${GITHUB_OUTPUT}"
echo "product-version-pre=${PRERELEASE}" | tee -a "${GITHUB_OUTPUT}"
echo "experiments=${EXPERIMENTS_ENABLED}" | tee -a "${GITHUB_OUTPUT}"
echo "go-ldflags=${LDFLAGS}" | tee -a "${GITHUB_OUTPUT}"

View File

@@ -1,49 +0,0 @@
#!/bin/bash
# Copyright (c) The OpenTofu Authors
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2023 HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
set -euo pipefail
# verify_docker invokes the given Docker image with the argument `version` and inspects its output.
# If its output doesn't match the version given, the script will exit 1 and report why it failed.
# This is meant to be run as part of the build workflow to verify the built image meets some basic
# criteria for validity.
#
# Because this is meant to be run as the `smoke_test` for the docker-build workflow, the script expects
# the image name parameter to be provided by the `IMAGE_NAME` environment variable, rather than a
# positional argument.
function usage {
echo "IMAGE_NAME=<image uri> ./verify_docker <expect_version>"
}
function main {
local image_name="${IMAGE_NAME:-}"
local expect_version="${1:-}"
local got_version
if [[ -z "${image_name}" ]]; then
echo "ERROR: IMAGE_NAME is not set"
usage
exit 1
fi
if [[ -z "${expect_version}" ]]; then
echo "ERROR: expected version argument is required"
usage
exit 1
fi
got_version="$( awk '{print $2}' <(head -n1 <(docker run --rm "${image_name}" version)) )"
if [ "${got_version}" != "${expect_version}" ]; then
echo "Test FAILED"
echo "Got: ${got_version}, Want: ${expect_version}"
exit 1
fi
echo "Test PASSED"
}
main "$@"

View File

@@ -1,40 +0,0 @@
name: Backport Merged Pull Request
on:
pull_request:
types:
- closed
- labeled
jobs:
backport:
name: Backport pull request
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Check if backport label exists in any of the labels on the pull request
id: check_backport_label
run: |
label_names="${{ join(github.event.pull_request.labels.*.name, ' ') }}"
if [[ "$label_names" == *"backport"* ]]; then
echo "has_backport_label=true" | tee -a "${GITHUB_OUTPUT}"
else
echo "has_backport_label=false" | tee -a "${GITHUB_OUTPUT}"
fi
- name: Run custom bash script for backporting
if: ${{ github.event.pull_request.state == 'closed' && github.event.pull_request.merged && steps.check_backport_label.outputs.has_backport_label == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
OWNER: ${{ github.event.repository.owner.login }}
REPO: ${{ github.event.repository.name }}
ISSUE_NUMBER: ${{ github.event.pull_request.number }}
HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
run: |
bash ./.github/scripts/backport/main.sh
shell: bash

View File

@@ -1,41 +0,0 @@
# This Dockerfile is not intended for general use, but is rather used to
# produce our "light" release packages as part of our official release
# pipeline.
#
# If you want to test this locally you'll need to set the three arguments
# to values realistic for what the hashicorp/actions-docker-build GitHub
# action would set, and ensure that there's a suitable "tofu" executable
# in the dist/linux/${TARGETARCH} directory.
FROM docker.io/alpine:latest AS default
# This is intended to be run from the hashicorp/actions-docker-build GitHub
# action, which sets these appropriately based on context.
ARG PRODUCT_VERSION=UNSPECIFIED
ARG PRODUCT_REVISION=UNSPECIFIED
ARG BIN_NAME=tofu
# This argument is set by the Docker toolchain itself, to the name
# of the CPU architecture we're building an image for.
# Our caller should've extracted the corresponding "tofu" executable
# into dist/linux/${TARGETARCH} for us to use.
ARG TARGETARCH
LABEL maintainer="OpenTofu Team"
# New standard version label.
LABEL version=$PRODUCT_VERSION
# Historical OpenTofu-specific label preserved for backward compatibility.
LABEL "com.tofu.version"="${PRODUCT_VERSION}"
RUN apk add --no-cache git openssh
# The hashicorp/actions-docker-build GitHub Action extracts the appropriate
# release package for our target architecture into the current working
# directory before running "docker build", which we'll then copy into the
# Docker image to make sure that we use an identical binary as all of the
# other official release channels.
COPY ["dist/linux/${TARGETARCH}/tofu", "/bin/tofu"]
ENTRYPOINT ["/bin/tofu"]

View File

@@ -1,105 +0,0 @@
---
name: build_opentofu
# This workflow is intended to be called by the build workflow. The crt make
# targets that are utilized automatically determine build metadata and
# handle building and packing OpenTofu.
on:
workflow_call:
inputs:
cgo-enabled:
type: string
default: 0
required: true
goos:
required: true
type: string
goarch:
required: true
type: string
go-version:
type: string
package-name:
type: string
default: tofu
bin-name:
type: string
default: tofu
product-version:
type: string
required: true
ld-flags:
type: string
required: true
runson:
type: string
required: true
jobs:
build:
runs-on: ${{ inputs.runson }}
name: OpenTofu ${{ inputs.goos }} ${{ inputs.goarch }} v${{ inputs.product-version }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ inputs.go-version }}
- name: Determine artifact basename
run: echo "ARTIFACT_BASENAME=${{ inputs.package-name }}_${{ inputs.product-version }}_${{ inputs.goos }}_${{ inputs.goarch }}.zip" >> $GITHUB_ENV
- name: Build OpenTofu
env:
GOOS: ${{ inputs.goos }}
GOARCH: ${{ inputs.goarch }}
GO_LDFLAGS: ${{ inputs.ld-flags }}
ACTIONSOS: ${{ inputs.runson }}
CGO_ENABLED: ${{ inputs.cgo-enabled }}
uses: hashicorp/actions-go-build@37358f6098ef21b09542d84a9814ebb843aa4e3e # v1.0.0
with:
bin_name: ${{ inputs.bin-name }}
product_name: ${{ inputs.product-name }}
product_version: ${{ inputs.product-version }}
go_version: ${{ inputs.go-version }}
os: ${{ inputs.goos }}
arch: ${{ inputs.goarch }}
reproducible: nope
instructions: |-
mkdir dist out
set -x
go build -ldflags "${{ inputs.ld-flags }}" -o dist/ ./cmd/tofu
zip -r -j out/${{ env.ARTIFACT_BASENAME }} dist/
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: ${{ env.ARTIFACT_BASENAME }}
path: out/${{ env.ARTIFACT_BASENAME }}
if-no-files-found: error
- if: ${{ inputs.goos == 'linux' }}
uses: hashicorp/actions-packaging-linux@514d75d0961adeddf1f928fb93b82f41735fc488 # v1.6.0
with:
name: "opentofu"
description: "OpenTofu enables you to safely and predictably create, change, and improve infrastructure. It is an open source tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned."
arch: ${{ inputs.goarch }}
version: ${{ inputs.product-version }}
maintainer: "HashiCorp"
homepage: "https://opentofu.org/"
license: "MPL-2.0"
binary: "dist/tofu"
deb_depends: "git"
rpm_depends: "git"
- if: ${{ inputs.goos == 'linux' }}
name: Determine package file names
run: |
echo "RPM_PACKAGE=$(basename out/*.rpm)" >> $GITHUB_ENV
echo "DEB_PACKAGE=$(basename out/*.deb)" >> $GITHUB_ENV
- if: ${{ inputs.goos == 'linux' }}
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: ${{ env.RPM_PACKAGE }}
path: out/${{ env.RPM_PACKAGE }}
if-no-files-found: error
- if: ${{ inputs.goos == 'linux' }}
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: ${{ env.DEB_PACKAGE }}
path: out/${{ env.DEB_PACKAGE }}
if-no-files-found: error

View File

@@ -1,109 +1,19 @@
name: build
# If you want to test changes to this file before merging to a main branch,
# push them up to a branch whose name has the prefix "build-workflow-dev/",
# which is a special prefix that triggers this workflow even though it's not
# actually a release branch.
on:
workflow_dispatch:
push:
branches:
- main
- 'v[0-9]+.[0-9]+'
- releng/**
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
env:
PKG_NAME: "tofu"
permissions:
contents: read
statuses: write
jobs:
get-product-version:
name: "Determine intended OpenTofu version"
runs-on: ubuntu-latest
outputs:
product-version: ${{ steps.get-product-version.outputs.product-version }}
product-version-base: ${{ steps.get-product-version.outputs.base-product-version }}
product-version-pre: ${{ steps.get-product-version.outputs.prerelease-product-version }}
experiments: ${{ steps.get-ldflags.outputs.experiments }}
go-ldflags: ${{ steps.get-ldflags.outputs.go-ldflags }}
pkg-name: ${{ steps.get-pkg-name.outputs.pkg-name }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get Package Name
id: get-pkg-name
run: |
pkg_name=${{ env.PKG_NAME }}
echo "pkg-name=${pkg_name}" | tee -a "${GITHUB_OUTPUT}"
- name: Decide version number
id: get-product-version
uses: hashicorp/actions-set-product-version@b426ea77cad0389738a8a81d89e933146a3ba97f # unreleased, untagged (upgrade of actions/checkout)
- name: Determine experiments
id: get-ldflags
env:
RAW_VERSION: ${{ steps.get-product-version.outputs.product-version }}
shell: bash
run: .github/scripts/get_product_version.sh
- name: Report chosen version number
run: |
[ -n "${{steps.get-product-version.outputs.product-version}}" ]
echo "::notice title=OpenTofu CLI Version::${{ steps.get-product-version.outputs.product-version }}"
get-go-version:
name: "Determine Go toolchain version"
runs-on: ubuntu-latest
outputs:
go-version: ${{ steps.get-go-version.outputs.version }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Determine Go version
id: get-go-version
uses: ./.github/actions/go-version
generate-metadata-file:
name: "Generate release metadata"
runs-on: ubuntu-latest
needs: get-product-version
outputs:
filepath: ${{ steps.generate-metadata-file.outputs.filepath }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Generate package metadata
id: generate-metadata-file
uses: hashicorp/actions-generate-metadata@f6f1ca9cededa05d841a58d171064faf3de8ec74 # unreleased, untagged (upgrade of multiple gha)
with:
version: ${{ needs.get-product-version.outputs.product-version }}
product: ${{ env.PKG_NAME }}
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: metadata.json
path: ${{ steps.generate-metadata-file.outputs.filepath }}
build:
name: Build for ${{ matrix.goos }}_${{ matrix.goarch }}
needs:
- get-product-version
- get-go-version
uses: ./.github/workflows/build-opentofu-oss.yml
with:
goarch: ${{ matrix.goarch }}
goos: ${{ matrix.goos }}
go-version: ${{ needs.get-go-version.outputs.go-version }}
package-name: ${{ needs.get-product-version.outputs.pkg-name }}
product-version: ${{ needs.get-product-version.outputs.product-version }}
ld-flags: ${{ needs.get-product-version.outputs.go-ldflags }}
cgo-enabled: ${{ matrix.cgo-enabled }}
runson: ${{ matrix.runson }}
secrets: inherit
strategy:
matrix:
include:
@@ -123,199 +33,61 @@ jobs:
- {goos: "darwin", goarch: "arm64", runson: "macos-latest", cgo-enabled: "1"}
fail-fast: false
package-docker:
name: Build Docker image for linux_${{ matrix.arch }}
name: Build for ${{ matrix.goos }}_${{ matrix.goarch }}
runs-on: ubuntu-latest
needs:
- get-product-version
- build
strategy:
matrix:
arch: ["amd64", "386", "arm", "arm64"]
fail-fast: false
env:
repo: "opentofu"
version: ${{needs.get-product-version.outputs.product-version}}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Build Docker images
uses: hashicorp/actions-docker-build@0635aed766f1f4e4519845ca22a4d024c96fb55d # unreleased, untagged (upgrade of multiple gha)
with:
pkg_name: "opentofu_${{env.version}}"
version: ${{env.version}}
bin_name: tofu
target: default
arch: ${{matrix.arch}}
dockerfile: .github/workflows/build-Dockerfile
smoke_test: .github/scripts/verify_docker v${{ env.version }}
tags: |
docker.io/opentofu/${{env.repo}}:${{env.version}}
public.ecr.aws/opentofu/${{env.repo}}:${{env.version}}
e2etest-build:
name: Build e2etest for ${{ matrix.goos }}_${{ matrix.goarch }}
runs-on: ubuntu-latest
outputs:
e2e-cache-key: ${{ steps.set-cache-values.outputs.e2e-cache-key }}
e2e-cache-path: ${{ steps.set-cache-values.outputs.e2e-cache-path }}
needs:
- get-product-version
- get-go-version
strategy:
matrix:
include:
- {goos: "darwin", goarch: "amd64"}
- {goos: "darwin", goarch: "arm64"}
- {goos: "windows", goarch: "amd64"}
- {goos: "windows", goarch: "386"}
- {goos: "linux", goarch: "386"}
- {goos: "linux", goarch: "amd64"}
- {goos: linux, goarch: "arm"}
- {goos: linux, goarch: "arm64"}
fail-fast: false
env:
build_script: ./internal/command/e2etest/make-archive.sh
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
steps:
- name: Set Cache Values
id: set-cache-values
run: |
cache_key=e2e-cache-${{ github.sha }}
cache_path=internal/command/e2etest/build
echo "e2e-cache-key=${cache_key}" | tee -a "${GITHUB_OUTPUT}"
echo "e2e-cache-path=${cache_path}" | tee -a "${GITHUB_OUTPUT}"
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: "Fetch source code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ needs.get-go-version.outputs.go-version }}
go-version-file: 'go.mod'
- name: Build test harness package
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GO_LDFLAGS: ${{ needs.get-product-version.outputs.go-ldflags }}
- name: "Build tofu executable"
run: |
# NOTE: This script reacts to the GOOS, GOARCH, and GO_LDFLAGS
# environment variables defined above. The e2e test harness
# needs to know the version we're building for so it can verify
# that "tofu version" is returning that version number.
bash ./internal/command/e2etest/make-archive.sh
go build ./cmd/tofu
- name: Save test harness to cache
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: ${{ steps.set-cache-values.outputs.e2e-cache-path }}
key: ${{ steps.set-cache-values.outputs.e2e-cache-key }}_${{ matrix.goos }}_${{ matrix.goarch }}
e2e-test:
name: Run e2e test for ${{ matrix.goos }}_${{ matrix.goarch }}
runs-on: ${{ matrix.runson }}
needs:
- get-product-version
- build
- e2etest-build
e2e-tests:
strategy:
matrix:
include:
- { runson: ubuntu-latest, goos: linux, goarch: "amd64" }
- { runson: ubuntu-latest, goos: linux, goarch: "386" }
- { runson: ubuntu-latest, goos: linux, goarch: "arm" }
- { runson: ubuntu-latest, goos: linux, goarch: "arm64" }
# - { runson: ubuntu-24.04-arm, goos: linux, goarch: "arm" } Disabled due to missing `template` provider, should switch it in the tests
# - { runson: ubuntu-24.04-arm, goos: linux, goarch: "arm64" } Disabled due to missing `template` provider, should switch it in the tests
- { runson: macos-latest, goos: darwin, goarch: "amd64" }
- { runson: windows-latest, goos: windows, goarch: "amd64" }
- { runson: windows-latest, goos: windows, goarch: "386" }
fail-fast: false
name: "End-to-end Tests for ${{ matrix.goos }}_${{ matrix.goarch }}"
runs-on: ${{ matrix.runson }}
env:
os: ${{ matrix.goos }}
arch: ${{ matrix.goarch }}
version: ${{needs.get-product-version.outputs.product-version}}
TF_APPEND_USER_AGENT: E2E-Test
TF_ACC: 1
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
steps:
# NOTE: This intentionally _does not_ check out the source code
# for the commit/tag we're building, because by now we should
# have everything we need in the combination of CLI release package
# and e2etest package for this platform. (This helps ensure that we're
# really testing the release package and not inadvertently testing a
# fresh build from source.)
- name: Checkout repo
if: ${{ (matrix.goos == 'linux') || (matrix.goos == 'darwin') }}
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: "Restore cache"
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
id: e2etestpkg
with:
path: ${{ needs.e2etest-build.outputs.e2e-cache-path }}
key: ${{ needs.e2etest-build.outputs.e2e-cache-key }}_${{ matrix.goos }}_${{ matrix.goarch }}
fail-on-cache-miss: true
enableCrossOsArchive: true
- name: "Download OpenTofu CLI package"
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
id: clipkg
with:
name: tofu_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip
path: .
- name: Extract packages
if: ${{ matrix.goos == 'windows' }}
run: |
unzip "${{ needs.e2etest-build.outputs.e2e-cache-path }}/tofu-e2etest_${{ env.os }}_${{ env.arch }}.zip"
unzip "./tofu_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip"
- name: Set up QEMU
# 👇🏾 GH actions supports only "AMD64 arch", so we are using this action
# for testing on non amd64 envs like 386, arm64 etc...
- name: "Set up QEMU"
if: matrix.goos == 'linux' && matrix.goarch != 'amd64' && matrix.goarch != 'arm64'
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0
if: ${{ contains(matrix.goarch, 'arm') }}
with:
platforms: all
- name: Run E2E Tests (Darwin & Linux)
id: get-product-version
shell: bash
if: ${{ (matrix.goos == 'linux') || (matrix.goos == 'darwin') }}
env:
e2e_cache_path: ${{ needs.e2etest-build.outputs.e2e-cache-path }}
run: .github/scripts/e2e_test_linux_darwin.sh
- name: Run E2E Tests (Windows)
if: ${{ matrix.goos == 'windows' }}
env:
TF_ACC: 1
shell: cmd
run: e2etest.exe -test.v
- name: "Fetch source code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
e2e-test-exec:
name: Run tofu-exec test for linux amd64
runs-on: ubuntu-latest
needs:
- get-product-version
- get-go-version
- build
env:
os: ${{ matrix.goos }}
arch: ${{ matrix.goarch }}
version: ${{needs.get-product-version.outputs.product-version}}
steps:
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ needs.get-go-version.outputs.go-version }}
- name: Download OpenTofu CLI package
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
id: clipkg
with:
name: tofu_${{ env.version }}_linux_amd64.zip
path: .
- name: Checkout tofu-exec repo
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
repository: opentofu/tofu-exec
path: tofu-exec
- name: Run tofu-exec end-to-end tests
go-version-file: 'go.mod'
- name: "End-to-end tests"
run: |
FULL_RELEASE_VERSION="${{ env.version }}"
unzip tofu_${FULL_RELEASE_VERSION}_linux_amd64.zip
export TFEXEC_E2ETEST_TERRAFORM_PATH="$(pwd)/tofu"
cd tofu-exec
go test -race -timeout=30m -v ./tfexec/internal/e2etest
go test -v ./internal/command/e2etest

View File

@@ -77,25 +77,10 @@ jobs:
- name: "Fetch source code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.version }}
# NOTE: This cache is shared so the following step must always be
# identical across the unit-tests, e2e-tests, and consistency-checks
# jobs, or else weird things could happen.
- name: Cache Go modules
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: "~/go/pkg"
key: go-mod-${{ hashFiles('go.sum') }}
restore-keys: |
go-mod-
go-version-file: 'go.mod'
- name: "Unit tests"
run: |
@@ -111,25 +96,10 @@ jobs:
- name: "Fetch source code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.version }}
# NOTE: This cache is shared so the following step must always be
# identical across the unit-tests, e2e-tests, and consistency-checks
# jobs, or else weird things could happen.
- name: Cache Go modules
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: "~/go/pkg"
key: go-mod-${{ hashFiles('go.sum') }}
restore-keys: |
go-mod-
go-version-file: 'go.mod'
# The race detector add significant time to the unit tests, so only run
# it for select packages.
@@ -151,25 +121,10 @@ jobs:
- name: "Fetch source code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.version }}
# NOTE: This cache is shared so the following step must always be
# identical across the unit-tests, e2e-tests, and consistency-checks
# jobs, or else weird things could happen.
- name: Cache Go modules
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: "~/go/pkg"
key: go-mod-${{ hashFiles('go.sum') }}
restore-keys: |
go-mod-
go-version-file: 'go.mod'
- name: "End-to-end tests"
run: |
@@ -187,25 +142,10 @@ jobs:
with:
fetch-depth: 0 # We need to do comparisons against the main branch.
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.version }}
# NOTE: This cache is shared so the following step must always be
# identical across the unit-tests, e2e-tests, and consistency-checks
# jobs, or else weird things could happen.
- name: Cache Go modules
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
with:
path: "~/go/pkg"
key: go-mod-${{ hashFiles('go.sum') }}
restore-keys: |
go-mod-
go-version-file: 'go.mod'
- name: "go.mod and go.sum consistency check"
run: |
@@ -266,14 +206,10 @@ jobs:
restore-keys: |
licensei-cache-
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.version }}
go-version-file: 'go.mod'
- name: Run licensei
env:

View File

@@ -34,14 +34,10 @@ jobs:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Set up Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.version }}
go-version-file: 'go.mod'
- name: Get the equivalence test binary
run: |

View File

@@ -33,14 +33,10 @@ jobs:
with:
ref: ${{matrix.branch}}
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Install Go toolchain
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{steps.go.outputs.version}}
go-version-file: 'go.mod'
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@d1f380186385b4f64e00313f31743df8e4b89a77 # v1.1.4

View File

@@ -70,14 +70,10 @@ jobs:
exit 1
fi
- name: Determine Go version
id: go
uses: ./.github/actions/go-version
- name: Set up Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # v5.3.0
with:
go-version: ${{ steps.go.outputs.version }}
go-version-file: 'go.mod'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0

View File

@@ -10,6 +10,7 @@ import (
"encoding/json"
"fmt"
"os"
"path"
"path/filepath"
"runtime"
"strings"
@@ -329,6 +330,20 @@ func TestInitProviders_pluginCache(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
extension := ""
if runtime.GOOS == "windows" {
extension = ".exe"
// Fix EXE path
target := path.Join(wantMachineDir, "terraform-provider-template_v2.1.0_x4")
err := os.Rename(target, target+extension)
if err != nil {
t.Fatal(err)
}
// TODO add .exe entry to lockfile
t.Skip()
}
cmd := tf.Cmd("init")
@@ -340,7 +355,7 @@ func TestInitProviders_pluginCache(t *testing.T) {
t.Errorf("unexpected error: %s", err)
}
path := filepath.FromSlash(fmt.Sprintf(".terraform/providers/registry.opentofu.org/hashicorp/template/2.1.0/%s_%s/terraform-provider-template_v2.1.0_x4", runtime.GOOS, runtime.GOARCH))
path := filepath.FromSlash(fmt.Sprintf(".terraform/providers/registry.opentofu.org/hashicorp/template/2.1.0/%s_%s/terraform-provider-template_v2.1.0_x4", runtime.GOOS, runtime.GOARCH)) + extension
content, err := tf.ReadFile(path)
if err != nil {
t.Fatalf("failed to read installed plugin from %s: %s", path, err)
@@ -349,18 +364,12 @@ func TestInitProviders_pluginCache(t *testing.T) {
t.Errorf("template plugin was not installed from local cache")
}
nullLinkPath := filepath.FromSlash(fmt.Sprintf(".terraform/providers/registry.opentofu.org/hashicorp/null/2.1.0/%s_%s/terraform-provider-null", runtime.GOOS, runtime.GOARCH))
if runtime.GOOS == "windows" {
nullLinkPath = nullLinkPath + ".exe"
}
nullLinkPath := filepath.FromSlash(fmt.Sprintf(".terraform/providers/registry.opentofu.org/hashicorp/null/2.1.0/%s_%s/terraform-provider-null", runtime.GOOS, runtime.GOARCH)) + extension
if !tf.FileExists(nullLinkPath) {
t.Errorf("null plugin was not installed into %s", nullLinkPath)
}
nullCachePath := filepath.FromSlash(fmt.Sprintf("cache/registry.opentofu.org/hashicorp/null/2.1.0/%s_%s/terraform-provider-null", runtime.GOOS, runtime.GOARCH))
if runtime.GOOS == "windows" {
nullCachePath = nullCachePath + ".exe"
}
nullCachePath := filepath.FromSlash(fmt.Sprintf("cache/registry.opentofu.org/hashicorp/null/2.1.0/%s_%s/terraform-provider-null", runtime.GOOS, runtime.GOARCH)) + extension
if !tf.FileExists(nullCachePath) {
t.Errorf("null plugin is not in cache after install. expected in: %s", nullCachePath)
}

View File

@@ -1,58 +0,0 @@
#!/bin/bash
# Copyright (c) The OpenTofu Authors
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2023 HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0
# For normal use this package can just be tested with "go test" as standard,
# but this script is an alternative to allow the tests to be run somewhere
# other than where they are built.
# The primary use for this is cross-compilation, where e.g. we can produce an
# archive that can be extracted on a Windows system to run the e2e tests there:
# $ GOOS=windows GOARCH=amd64 ./make-archive.sh
#
# This will produce a zip file build/terraform-e2etest_windows_amd64.zip which
# can be shipped off to a Windows amd64 system, extracted to some directory,
# and then executed as follows:
# set TF_ACC=1
# ./e2etest.exe
#
# Because separated e2etest harnesses are intended for testing against "real"
# release executables, the generated archives don't include a copy of
# the Terraform executable. Instead, the caller of the tests must retrieve
# and extract a release package into the working directory before running
# the e2etest executable, so that "e2etest" can find and execute it.
set +euo pipefail
# Always run from the directory where this script lives
cd "$( dirname "${BASH_SOURCE[0]}" )"
GOOS="$(go env GOOS)"
GOARCH="$(go env GOARCH)"
GOEXE="$(go env GOEXE)"
OUTDIR="build/${GOOS}_${GOARCH}"
OUTFILE="tofu-e2etest_${GOOS}_${GOARCH}.zip"
LDFLAGS="-X github.com/opentofu/opentofu/internal/command/e2etest.tofuBin=./tofu$GOEXE"
# Caller may pass in the environment variable GO_LDFLAGS with additional
# flags we'll use when building.
if [ -n "${GO_LDFLAGS+set}" ]; then
LDFLAGS="${GO_LDFLAGS} ${LDFLAGS}"
fi
mkdir -p "$OUTDIR"
# We need the test fixtures available when we run the tests.
cp -r testdata "$OUTDIR/testdata"
# Build the test program
go test -o "$OUTDIR/e2etest$GOEXE" -c -ldflags "$LDFLAGS" github.com/opentofu/opentofu/internal/command/e2etest
# Now bundle it all together for easy shipping!
cd "$OUTDIR"
zip -r "../$OUTFILE" *
echo "e2etest archive created at build/$OUTFILE"

View File

@@ -9,6 +9,7 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"testing"
@@ -42,6 +43,11 @@ func TestProviderProtocols(t *testing.T) {
simpleProvider := filepath.Join(tf.WorkDir(), "terraform-provider-simple")
simpleProviderExe := e2e.GoBuild("github.com/opentofu/opentofu/internal/provider-simple/main", simpleProvider)
extension := ""
if runtime.GOOS == "windows" {
extension = ".exe"
}
// Move the provider binaries into a directory that we will point tofu
// to using the -plugin-dir cli flag.
platform := getproviders.CurrentPlatform.String()
@@ -49,14 +55,14 @@ func TestProviderProtocols(t *testing.T) {
if err := os.MkdirAll(tf.Path(hashiDir, "simple6/0.0.1/", platform), os.ModePerm); err != nil {
t.Fatal(err)
}
if err := os.Rename(simple6ProviderExe, tf.Path(hashiDir, "simple6/0.0.1/", platform, "terraform-provider-simple6")); err != nil {
if err := os.Rename(simple6ProviderExe, tf.Path(hashiDir, "simple6/0.0.1/", platform, "terraform-provider-simple6")+extension); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(tf.Path(hashiDir, "simple/0.0.1/", platform), os.ModePerm); err != nil {
t.Fatal(err)
}
if err := os.Rename(simpleProviderExe, tf.Path(hashiDir, "simple/0.0.1/", platform, "terraform-provider-simple")); err != nil {
if err := os.Rename(simpleProviderExe, tf.Path(hashiDir, "simple/0.0.1/", platform, "terraform-provider-simple")+extension); err != nil {
t.Fatal(err)
}

View File

@@ -8,6 +8,7 @@ package e2etest
import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"
@@ -41,8 +42,13 @@ func TestProvisionerPlugin(t *testing.T) {
provisionerExePrefix := filepath.Join(tf.WorkDir(), "terraform-provisioner-test_")
provisionerExe := e2e.GoBuild("github.com/opentofu/opentofu/internal/provisioner-local-exec/main", provisionerExePrefix)
extension := ""
if runtime.GOOS == "windows" {
extension = ".exe"
}
// provisioners must use the old binary name format, so rename this binary
newExe := filepath.Join(tf.WorkDir(), "terraform-provisioner-test")
newExe := filepath.Join(tf.WorkDir(), "terraform-provisioner-test") + extension
if _, err := os.Stat(newExe); !os.IsNotExist(err) {
t.Fatalf("%q already exists", newExe)
}

View File

@@ -12,6 +12,7 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"testing"
"github.com/opentofu/opentofu/internal/encryption"
@@ -235,6 +236,10 @@ func (b *binary) SetLocalState(state *states.State) error {
}
func GoBuild(pkgPath, tmpPrefix string) string {
if runtime.GOOS == "windows" {
tmpPrefix += ".exe"
}
dir, prefix := filepath.Split(tmpPrefix)
tmpFile, err := os.CreateTemp(dir, prefix)
if err != nil {