github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/.github/workflows/build.yml (about)

     1  name: Build Terraform CLI Packages
     2  
     3  # If you want to test changes to this file before merging to a main branch,
     4  # push them up to a branch whose name has the prefix "build-workflow-dev/",
     5  # which is a special prefix that triggers this workflow even though it's not
     6  # actually a release branch.
     7  
     8  # NOTE: This workflow is currently used only to verify that all commits to a
     9  # release branch are buildable. It's set up to generate some artifacts that
    10  # might in principle be consumed by a downstream release process, but currently
    11  # they are not used in this way and official Terraform CLI releases are instead
    12  # built using a separate process maintained elsewhere. We intend to adopt this
    13  # new process fully later, once other HashiCorp-internal tooling is ready.
    14  #
    15  # Currently this process produces what should be working packages but packages
    16  # NOT suitable for distribution to end-users as official releases, because it
    17  # doesn't include a step to ensure that "terraform version" (and similar) will
    18  # report the intended version number. Consequently we can safely use these
    19  # results for testing purposes, but not yet for release purposes. See the
    20  # "build" job below for a FIXME comment related to version numbers.
    21  
    22  on:
    23    workflow_dispatch:
    24    push:
    25      branches:
    26        - main
    27        - 'v[0-9]+.[0-9]+'
    28        - build-workflow-dev/*
    29      tags:
    30        - 'v[0-9]+.[0-9]+.[0-9]+*'
    31  
    32  env:
    33    PKG_NAME: "terraform"
    34  
    35  permissions:
    36    contents: read
    37    statuses: write
    38  
    39  jobs:
    40    get-product-version:
    41      name: "Determine intended Terraform version"
    42      runs-on: ubuntu-latest
    43      outputs:
    44        product-version: ${{ steps.get-product-version.outputs.product-version }}
    45        product-version-base: ${{ steps.get-product-version.outputs.product-version-base }}
    46        product-version-pre: ${{ steps.get-product-version.outputs.product-version-pre }}
    47        experiments: ${{ steps.get-product-version.outputs.experiments }}
    48        go-ldflags: ${{ steps.get-product-version.outputs.go-ldflags }}
    49  
    50      steps:
    51        - uses: actions/checkout@v3
    52        - name: Git Describe
    53          id: git-describe
    54          run: |
    55            # The actions/checkout action tries hard to fetch as little as
    56            # possible, to the extent that even with "depth: 0" it fails to
    57            # produce enough tag metadata for us to "describe" successfully.
    58            # We'll therefore re-fetch the tags here to make sure we will
    59            # select the most accurate version number.
    60            git fetch origin --force --tags --quiet --unshallow
    61            git log --tags --simplify-by-decoration --decorate-refs='refs/tags/v*' --pretty=format:'%h %<|(35)%S %ci' --max-count 15 --topo-order
    62            set -e
    63            RAW_VERSION=$(git describe --tags --match='v*' ${GITHUB_SHA})
    64            echo "
    65            
    66            Raw version is ${RAW_VERSION}"
    67            echo "::set-output name=raw-version::${RAW_VERSION}"
    68        - name: Decide version number
    69          id: get-product-version
    70          shell: bash
    71          env:
    72            RAW_VERSION: ${{ steps.git-describe.outputs.raw-version }}
    73          run: |
    74            # Trim the "v" prefix, if any.
    75            VERSION="${RAW_VERSION#v}"
    76  
    77            # Split off the build metadata part, if any
    78            # (we won't actually include it in our final version, and handle it only for
    79            # compleness against semver syntax.)
    80            IFS='+' read -ra VERSION BUILD_META <<< "$VERSION"
    81  
    82            # Separate out the prerelease part, if any
    83            # (version.go expects it to be in a separate variable)
    84            IFS='-' read -r BASE_VERSION PRERELEASE <<< "$VERSION"
    85  
    86            EXPERIMENTS_ENABLED=0
    87            if [[ "$PRERELEASE" == alpha* ]]; then
    88              EXPERIMENTS_ENABLED=1
    89            fi
    90            if [[ "$PRERELEASE" == dev* ]]; then
    91              EXPERIMENTS_ENABLED=1
    92            fi
    93  
    94            LDFLAGS="-w -s"
    95            if [[ "$EXPERIMENTS_ENABLED" == 1 ]]; then
    96              LDFLAGS="${LDFLAGS} -X 'main.experimentsAllowed=yes'"
    97            fi
    98            LDFLAGS="${LDFLAGS} -X 'github.com/hashicorp/terraform/version.Version=${BASE_VERSION}'"
    99            LDFLAGS="${LDFLAGS} -X 'github.com/hashicorp/terraform/version.Prerelease=${PRERELEASE}'"
   100  
   101            echo "Building Terraform CLI ${VERSION}"
   102            if [[ "$EXPERIMENTS_ENABLED" == 1 ]]; then
   103              echo "This build allows use of experimental features"
   104            fi
   105            echo "::set-output name=product-version::${VERSION}"
   106            echo "::set-output name=product-version-base::${BASE_VERSION}"
   107            echo "::set-output name=product-version-pre::${PRERELEASE}"
   108            echo "::set-output name=experiments::${EXPERIMENTS_ENABLED}"
   109            echo "::set-output name=go-ldflags::${LDFLAGS}"
   110        - name: Report chosen version number
   111          run: |
   112            [ -n "${{steps.get-product-version.outputs.product-version}}" ]
   113            echo "::notice title=Terraform CLI Version::${{ steps.get-product-version.outputs.product-version }}"
   114  
   115    get-go-version:
   116      name: "Determine Go toolchain version"
   117      runs-on: ubuntu-latest
   118      outputs:
   119        go-version: ${{ steps.get-go-version.outputs.version }}
   120  
   121      steps:
   122        - uses: actions/checkout@v2
   123        - name: Determine Go version
   124          id: get-go-version
   125          uses: ./.github/actions/go-version
   126  
   127    generate-metadata-file:
   128      name: "Generate release metadata"
   129      runs-on: ubuntu-latest
   130      needs: get-product-version
   131      outputs:
   132        filepath: ${{ steps.generate-metadata-file.outputs.filepath }}
   133  
   134      steps:
   135        - uses: actions/checkout@v2
   136        - name: Generate package metadata
   137          id: generate-metadata-file
   138          uses: hashicorp/actions-generate-metadata@v1
   139          with:
   140            version: ${{ needs.get-product-version.outputs.product-version }}
   141            product: ${{ env.PKG_NAME }}
   142  
   143        - uses: actions/upload-artifact@v2
   144          with:
   145            name: metadata.json
   146            path: ${{ steps.generate-metadata-file.outputs.filepath }}
   147  
   148    build:
   149      name: Build for ${{ matrix.goos }}_${{ matrix.goarch }}
   150      runs-on: ${{ matrix.runson }}
   151      needs:
   152        - get-product-version
   153        - get-go-version
   154      strategy:
   155        matrix:
   156          include:
   157            - {goos: "freebsd", goarch: "386", runson: "ubuntu-latest"}
   158            - {goos: "freebsd", goarch: "amd64", runson: "ubuntu-latest"}
   159            - {goos: "freebsd", goarch: "arm", runson: "ubuntu-latest"}
   160            - {goos: "linux", goarch: "386", runson: "ubuntu-latest"}
   161            - {goos: "linux", goarch: "amd64", runson: "ubuntu-latest"}
   162            - {goos: "linux", goarch: "arm", runson: "ubuntu-latest"}
   163            - {goos: "linux", goarch: "arm64", runson: "ubuntu-latest"}
   164            - {goos: "openbsd", goarch: "386", runson: "ubuntu-latest"}
   165            - {goos: "openbsd", goarch: "amd64", runson: "ubuntu-latest"}
   166            - {goos: "solaris", goarch: "amd64", runson: "ubuntu-latest"}
   167            - {goos: "windows", goarch: "386", runson: "ubuntu-latest"}
   168            - {goos: "windows", goarch: "amd64", runson: "ubuntu-latest"}
   169            - {goos: "darwin", goarch: "amd64", runson: "macos-latest"}
   170            - {goos: "darwin", goarch: "arm64", runson: "macos-latest"}
   171        fail-fast: false
   172  
   173      env:
   174        FULL_VERSION: ${{ needs.get-product-version.outputs.product-version }}
   175        BASE_VERSION: ${{ needs.get-product-version.outputs.product-version-base }}
   176        VERSION_PRERELEASE: ${{ needs.get-product-version.outputs.product-version-pre }}
   177        EXPERIMENTS_ENABLED: ${{ needs.get-product-version.outputs.experiments }}
   178        GO_LDFLAGS: ${{ needs.get-product-version.outputs.go-ldflags }}
   179  
   180      steps:
   181        - uses: actions/checkout@v2
   182  
   183        - name: Install Go toolchain
   184          uses: actions/setup-go@v2
   185          with:
   186            go-version: ${{ needs.get-go-version.outputs.go-version }}
   187  
   188        # FIXME: We're not currently setting the hard-coded version string in
   189        # version/version.go at any point here, which means that the packages
   190        # this process builds are not suitable for release. Once we're using
   191        # Go 1.18 we may begin using the version information automatically
   192        # embedded by the Go toolchain, at which point we won't need any
   193        # special steps during build, but failing that we'll need to rework
   194        # the version/version.go package so we can more readily update it
   195        # using linker flags rather than direct code modification.
   196  
   197        - name: Build
   198          env:
   199            GOOS: ${{ matrix.goos }}
   200            GOARCH: ${{ matrix.goarch }}
   201            ACTIONSOS: ${{ matrix.runson }}
   202          run: |
   203            mkdir dist out
   204            if [ "$ACTIONSOS" == "macos-latest" ] && [ "$GOOS" == "darwin" ]; then
   205              # When building for macOS _on_ macOS we must force CGo to get
   206              # correct hostname resolution behavior. (This must be conditional
   207              # because other cross-compiles won't have suitable headers
   208              # available to use CGo; darwin_amd64 has suitable headers to
   209              # cross-build for darwin_arm64.)
   210              export CGO_ENABLED=1
   211            fi
   212            set -x
   213            go build -ldflags "${GO_LDFLAGS}" -o dist/ .
   214            zip -r -j out/${{ env.PKG_NAME }}_${FULL_VERSION}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/
   215  
   216        - uses: actions/upload-artifact@v2
   217          with:
   218            name: ${{ env.PKG_NAME }}_${{ env.FULL_VERSION }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip
   219            path: out/${{ env.PKG_NAME }}_${{ env.FULL_VERSION }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip
   220  
   221    package-linux:
   222      name: "Build Linux distro packages for ${{ matrix.arch }}"
   223      runs-on: ubuntu-latest
   224      needs:
   225        - get-product-version
   226        - build
   227      strategy:
   228        matrix:
   229          include:
   230            - {arch: "386"}
   231            - {arch: "amd64"}
   232            - {arch: "arm"}
   233            - {arch: "arm64"}
   234        fail-fast: false
   235  
   236      env:
   237        os: linux
   238        arch: ${{matrix.arch}}
   239        version: ${{needs.get-product-version.outputs.product-version}}
   240  
   241      steps:
   242        - name: "Download Terraform CLI package"
   243          uses: actions/download-artifact@v2
   244          id: clipkg
   245          with:
   246            name: terraform_${{ env.version }}_${{ env.os }}_${{ env.arch }}.zip
   247            path: .
   248        - name: Extract packages
   249          run: |
   250            mkdir -p dist
   251            (cd dist && unzip "../terraform_${{ env.version }}_${{ env.os }}_${{ env.arch }}.zip")
   252            mkdir -p out
   253        - name: Build Linux distribution packages
   254          uses: hashicorp/actions-packaging-linux@v1
   255          with:
   256            name: "terraform"
   257            description: "Terraform 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."
   258            arch: ${{ matrix.arch }}
   259            version: ${{ env.version }}
   260            maintainer: "HashiCorp"
   261            homepage: "https://terraform.io/"
   262            license: "MPL-2.0"
   263            binary: "dist/terraform"
   264            deb_depends: "git"
   265            rpm_depends: "git"
   266        - name: Gather Linux distribution package filenames
   267          run: |
   268            echo "RPM_PACKAGE=$(basename out/*.rpm)" >> $GITHUB_ENV
   269            echo "DEB_PACKAGE=$(basename out/*.deb)" >> $GITHUB_ENV
   270        - name: "Save .rpm package"
   271          uses: actions/upload-artifact@v2
   272          with:
   273            name: ${{ env.RPM_PACKAGE }}
   274            path: out/${{ env.RPM_PACKAGE }}
   275        - name: "Save .deb package"
   276          uses: actions/upload-artifact@v2
   277          with:
   278            name: ${{ env.DEB_PACKAGE }}
   279            path: out/${{ env.DEB_PACKAGE }}
   280  
   281    # TODO: homebrew packages for macOS
   282    #package-homebrew:
   283    #  name: Build Homebrew package for darwin_${{ matrix.arch }}
   284    #  runs-on: macos-latest
   285    #  needs:
   286    #    - get-product-version
   287    #    - build
   288    #  strategy:
   289    #    matrix:
   290    #      arch: ["amd64", "arm64"]
   291    #    fail-fast: false
   292    # ...
   293  
   294    package-docker:
   295      name: Build Docker image for linux_${{ matrix.arch }}
   296      runs-on: ubuntu-latest
   297      needs:
   298        - get-product-version
   299        - build
   300      strategy:
   301        matrix:
   302          arch: ["amd64"]
   303        fail-fast: false
   304  
   305      env:
   306        repo: "terraform"
   307        version: ${{needs.get-product-version.outputs.product-version}}
   308  
   309      steps:
   310        - uses: actions/checkout@v2
   311        - name: Build Docker images
   312          uses: hashicorp/actions-docker-build@v1
   313          with:
   314            pkg_name: "terraform_${{env.version}}"
   315            version: ${{env.version}}
   316            bin_name: terraform
   317            target: default
   318            arch: ${{matrix.arch}}
   319            dockerfile: .github/workflows/build-Dockerfile
   320            tags: |
   321              docker.io/hashicorp/${{env.repo}}:${{env.version}}
   322              986891699432.dkr.ecr.us-east-1.amazonaws.com/hashicorp/${{env.repo}}:${{env.version}}
   323  
   324    e2etest-build:
   325      name: Build e2etest for ${{ matrix.goos }}_${{ matrix.goarch }}
   326      runs-on: ubuntu-latest
   327      needs:
   328        - get-product-version
   329        - get-go-version
   330      strategy:
   331        matrix:
   332          # We build test harnesses only for the v1.0 Compatibility Promises
   333          # supported platforms. Even within that set, we can only run on
   334          # architectures for which we have GitHub Actions runners available,
   335          # which is currently only amd64 (x64).
   336          # TODO: GitHub Actions does support _self-hosted_ arm and arm64
   337          # runners, so we could potentially run some ourselves to run our
   338          # tests there, but at the time of writing there is no documented
   339          # support for darwin_arm64 (macOS on Apple Silicon).
   340          include:
   341            - {goos: "darwin", goarch: "amd64"}
   342            #- {goos: "darwin", goarch: "arm64"}
   343            - {goos: "windows", goarch: "amd64"}
   344            - {goos: "linux", goarch: "amd64"}
   345            #- {goos: "linux", goarch: "arm"}
   346            #- {goos: "linux", goarch: "arm64"}
   347        fail-fast: false
   348  
   349      env:
   350        build_script: ./internal/command/e2etest/make-archive.sh
   351  
   352      steps:
   353        - uses: actions/checkout@v2
   354  
   355        - name: Install Go toolchain
   356          uses: actions/setup-go@v2
   357          with:
   358            go-version: ${{ needs.get-go-version.outputs.go-version }}
   359  
   360        - name: Build test harness package
   361          env:
   362            GOOS: ${{ matrix.goos }}
   363            GOARCH: ${{ matrix.goarch }}
   364            GO_LDFLAGS: ${{ needs.get-product-version.outputs.go-ldflags }}
   365          run: |
   366            # NOTE: This script reacts to the GOOS, GOARCH, and GO_LDFLAGS
   367            # environment variables defined above. The e2e test harness
   368            # needs to know the version we're building for so it can verify
   369            # that "terraform version" is returning that version number.
   370            bash ./internal/command/e2etest/make-archive.sh
   371  
   372        - uses: actions/upload-artifact@v2
   373          with:
   374            name: terraform-e2etest_${{ matrix.goos }}_${{ matrix.goarch }}.zip
   375            path: internal/command/e2etest/build/terraform-e2etest_${{ matrix.goos }}_${{ matrix.goarch }}.zip
   376            if-no-files-found: error
   377  
   378    e2etest-linux:
   379      name: e2etest for linux_${{ matrix.goarch }}
   380      runs-on: ubuntu-latest
   381      needs:
   382        - get-product-version
   383        - build
   384        - e2etest-build
   385      strategy:
   386        matrix:
   387          include:
   388            - {goarch: "amd64"}
   389            #- {goarch: "arm64"}
   390            #- {goarch: "arm"}
   391        fail-fast: false
   392  
   393      env:
   394        os: linux
   395        arch: ${{ matrix.goarch }}
   396        version: ${{needs.get-product-version.outputs.product-version}}
   397  
   398      steps:
   399        # NOTE: This intentionally _does not_ check out the source code
   400        # for the commit/tag we're building, because by now we should
   401        # have everything we need in the combination of CLI release package
   402        # and e2etest package for this platform. (This helps ensure that we're
   403        # really testing the release package and not inadvertently testing a
   404        # fresh build from source.)
   405        - name: "Download e2etest package"
   406          uses: actions/download-artifact@v2
   407          id: e2etestpkg
   408          with:
   409            name: terraform-e2etest_${{ env.os }}_${{ env.arch }}.zip
   410            path: .
   411        - name: "Download Terraform CLI package"
   412          uses: actions/download-artifact@v2
   413          id: clipkg
   414          with:
   415            name: terraform_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip
   416            path: .
   417        - name: Extract packages
   418          run: |
   419            unzip "./terraform-e2etest_${{ env.os }}_${{ env.arch }}.zip"
   420            unzip "./terraform_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip"
   421        - name: Run E2E Tests
   422          run: |
   423            TF_ACC=1 ./e2etest -test.v
   424  
   425    e2etest-darwin:
   426      name: e2etest for darwin_${{ matrix.goarch }}
   427      runs-on: macos-latest
   428      needs:
   429        - get-product-version
   430        - build
   431        - e2etest-build
   432      strategy:
   433        matrix:
   434          include:
   435            - {goarch: "amd64"}
   436            #- {goarch: "arm64"}
   437        fail-fast: false
   438  
   439      env:
   440        os: darwin
   441        arch: ${{ matrix.goarch }}
   442        version: ${{needs.get-product-version.outputs.product-version}}
   443  
   444      steps:
   445        # NOTE: This intentionally _does not_ check out the source code
   446        # for the commit/tag we're building, because by now we should
   447        # have everything we need in the combination of CLI release package
   448        # and e2etest package for this platform. (This helps ensure that we're
   449        # really testing the release package and not inadvertently testing a
   450        # fresh build from source.)
   451        - name: "Download e2etest package"
   452          uses: actions/download-artifact@v2
   453          id: e2etestpkg
   454          with:
   455            name: terraform-e2etest_${{ env.os }}_${{ env.arch }}.zip
   456            path: .
   457        - name: "Download Terraform CLI package"
   458          uses: actions/download-artifact@v2
   459          id: clipkg
   460          with:
   461            name: terraform_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip
   462            path: .
   463        - name: Extract packages
   464          run: |
   465            unzip "./terraform-e2etest_${{ env.os }}_${{ env.arch }}.zip"
   466            unzip "./terraform_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip"
   467        - name: Run E2E Tests
   468          run: |
   469            TF_ACC=1 ./e2etest -test.v
   470  
   471    e2etest-windows:
   472      name: e2etest for windows_${{ matrix.goarch }}
   473      runs-on: windows-latest
   474      needs:
   475        - get-product-version
   476        - build
   477        - e2etest-build
   478      strategy:
   479        matrix:
   480          include:
   481            - {goarch: "amd64"}
   482        fail-fast: false
   483  
   484      env:
   485        os: windows
   486        arch: ${{ matrix.goarch }}
   487        version: ${{needs.get-product-version.outputs.product-version}}
   488  
   489      steps:
   490        # NOTE: This intentionally _does not_ check out the source code
   491        # for the commit/tag we're building, because by now we should
   492        # have everything we need in the combination of CLI release package
   493        # and e2etest package for this platform. (This helps ensure that we're
   494        # really testing the release package and not inadvertently testing a
   495        # fresh build from source.)
   496        - name: "Download e2etest package"
   497          uses: actions/download-artifact@v2
   498          id: e2etestpkg
   499          with:
   500            name: terraform-e2etest_${{ env.os }}_${{ env.arch }}.zip
   501            path: .
   502        - name: "Download Terraform CLI package"
   503          uses: actions/download-artifact@v2
   504          id: clipkg
   505          with:
   506            name: terraform_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip
   507            path: .
   508        - name: Extract packages
   509          shell: pwsh
   510          run: |
   511            Expand-Archive -LiteralPath 'terraform-e2etest_${{ env.os }}_${{ env.arch }}.zip' -DestinationPath '.'
   512            Expand-Archive -LiteralPath 'terraform_${{env.version}}_${{ env.os }}_${{ env.arch }}.zip' -DestinationPath '.'
   513        - name: Run E2E Tests
   514          env:
   515            TF_ACC: 1
   516          shell: cmd
   517          run: |
   518            e2etest.exe -test.v
   519  
   520    docs-source-package:
   521      name: "Build documentation bundle"
   522      runs-on: ubuntu-latest
   523      needs:
   524        - get-product-version
   525  
   526      env:
   527        version: ${{needs.get-product-version.outputs.product-version}}
   528  
   529      steps:
   530        - uses: actions/checkout@v2
   531        # FIXME: We should include some sort of pre-validation step here, to
   532        # confirm that the doc content is mechanically valid so that the
   533        # publishing pipeline will be able to render all content without errors.
   534        - name: "Create documentation source bundle"
   535          run: |
   536            (cd website && zip -9 -r ../terraform-cli-docs-source_${{ env.version }}.zip .)
   537        - uses: actions/upload-artifact@v2
   538          with:
   539            name: terraform-cli-docs-source_${{ env.version }}.zip
   540            path: terraform-cli-docs-source_${{ env.version }}.zip
   541            if-no-files-found: error