name: build on: push: branches: - main - release-v* - release-next pull_request: workflow_dispatch: # cancel older, redundant runs of same workflow on same branch concurrency: group: ${{ github.workflow }}-${{github.event_name}}-${{ github.head_ref || github.ref_name }} cancel-in-progress: true env: GOFLAGS: "-trimpath" GOX_OUTPUT: "release/{{.Arch}}/{{.OS}}/{{.Dir}}" GOX_TEST_OUTPUT: "test/{{.Arch}}/{{.OS}}/bin/{{.Dir}}" AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_DEFAULT_REGION: "us-east-2" gh_ci_key: ${{ secrets.GH_CI_KEY }} CONSUL_ENCRYPTION_KEY: ${{ secrets.CONSUL_ENCRYPTION_KEY }} ELASTIC_ENDPOINT: ${{ secrets.ELASTIC_ENDPOINT }} ELASTIC_USERNAME: ${{ secrets.ELASTIC_USERNAME }} ELASTIC_PASSWORD: ${{ secrets.ELASTIC_PASSWORD }} CONSUL_ENDPOINT: ${{ secrets.CONSUL_ENDPOINT }} CONSUL_AGENT_CERT: ${{ secrets.CONSUL_AGENT_CERT }} BUILD_NUMBER: ${{ format('{0}-{1}-{2}', github.run_id, github.run_number, github.run_attempt) }} jobs: mac-os-build: name: Build Mac OS binaries # allow fors to opt-out of time-consuming macOS builds if: vars.ZITI_SKIP_MACOS_BUILD != 'true' runs-on: macos-11 steps: - name: Git Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Install Ziti CI uses: openziti/ziti-ci@v1 - name: Build and Test shell: bash run: | go install github.com/mitchellh/gox@latest $(go env GOPATH)/bin/ziti-ci generate-build-info common/version/info_generated.go version $(go env GOPATH)/bin/gox -cgo -os=darwin -arch=amd64 -output=$GOX_OUTPUT ./... $(go env GOPATH)/bin/gox -cgo -os=darwin -arch=arm64 -output=$GOX_OUTPUT ./... - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: darwin-release-${{ github.run_id }} path: release/ retention-days: 5 windows-build: name: Build Windows binaries # allow fors to opt-out of time-consuming Windows builds if: vars.ZITI_SKIP_WINDOWS_BUILD != 'true' runs-on: windows-2019 steps: - name: Git Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Install Ziti CI uses: openziti/ziti-ci@v1 - name: Build and Test shell: bash run: | go install github.com/mitchellh/gox@latest $(go env GOPATH)/bin/ziti-ci generate-build-info common/version/info_generated.go version $(go env GOPATH)/bin/gox -cgo -os=windows -arch=amd64 -output=$GOX_OUTPUT ./... - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: windows-release-${{ github.run_id }} path: release/ retention-days: 5 linux-build: name: Build Linux binaries runs-on: ubuntu-20.04 steps: - name: Git Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Install Ziti CI uses: openziti/ziti-ci@v1 - name: Build and Test shell: bash run: | sudo apt-get update sudo apt-get -yq install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gcc-aarch64-linux-gnu $(go env GOPATH)/bin/ziti-ci configure-git $(go env GOPATH)/bin/ziti-ci generate-build-info common/version/info_generated.go version go install github.com/mitchellh/gox@latest $(go env GOPATH)/bin/gox -cgo -os=linux -arch=amd64 -output=$GOX_OUTPUT ./... CC=arm-linux-gnueabihf-gcc $(go env GOPATH)/bin/gox -cgo -os=linux -arch=arm -output=$GOX_OUTPUT ./... CC=aarch64-linux-gnu-gcc $(go env GOPATH)/bin/gox -cgo -os=linux -arch=arm64 -output=$GOX_OUTPUT ./... - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: linux-release-${{ github.run_id }} path: release/ retention-days: 5 tests: name: Run Unit and Integration Tests runs-on: ubuntu-20.04 steps: - name: Git Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Install Ziti CI uses: openziti/ziti-ci@v1 - name: Run Go Quickstart Test timeout-minutes: 5 shell: bash run: | go test -v -tags "quickstart automated" ./ziti/cmd/edge/...; - name: Run Unit and Integration Tests timeout-minutes: 10 shell: bash run: | go test ./... --tags apitests fablab-smoketest: name: Fablab Smoketest # not applicable to forks. shouldn't run on release build if: github.repository_owner == 'openziti' && github.ref != 'refs/heads/main' runs-on: ubuntu-20.04 steps: - name: Git Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Install Ziti CI uses: openziti/ziti-ci@v1 - name: Build and Test env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ziti_ci_gpg_key: ${{ secrets.ZITI_CI_GPG_KEY }} ziti_ci_gpg_key_id: ${{ secrets.ZITI_CI_GPG_KEY_ID }} shell: bash run: | $(go env GOPATH)/bin/ziti-ci configure-git $(go env GOPATH)/bin/ziti-ci generate-build-info common/version/info_generated.go version go test ./... pushd zititest && go install ./... && popd go install -tags=all,tests ./... - name: Create Test Environment shell: bash run: | echo "ZITI_ROOT=$(go env GOPATH)/bin" >> "$GITHUB_ENV" $(go env GOPATH)/bin/smoketest create -d smoketest-${GITHUB_RUN_NUMBER} -n smoketest-${GITHUB_RUN_NUMBER} -l environment=gh-fablab-smoketest,ziti_version=$($(go env GOPATH)/bin/ziti-ci -q get-current-version) $(go env GOPATH)/bin/smoketest up - name: Test Ziti Command shell: bash run: | echo "ZITI_ROOT=$(go env GOPATH)/bin" >> "$GITHUB_ENV" pushd zititest && go test -timeout 30m -v ./tests/... 2>&1 | tee test.out && popd - name: Create fablab instance archive # always create, even if cancelled, because the teardown job needs it to destroy the created test environment if: always() timeout-minutes: 30 env: FABLAB_PASSPHRASE: ${{ secrets.FABLAB_PASSPHRASE }} shell: bash run: | cp $(go env GOPATH)/bin/smoketest smoketest-${GITHUB_RUN_NUMBER} cp ~/.fablab/config.yml smoketest-${GITHUB_RUN_NUMBER}/ tar --exclude *terraform-provider-aws* -czvf - smoketest-${GITHUB_RUN_NUMBER}/ | gpg --symmetric --cipher-algo aes256 --batch --quiet --passphrase ${FABLAB_PASSPHRASE} -o smoketest-${GITHUB_RUN_NUMBER}.tar.gz.gpg aws s3 cp ./smoketest-${GITHUB_RUN_NUMBER}.tar.gz.gpg s3://ziti-smoketest-fablab-instances/ - name: Create Logs Archive if: always() run: | $(go env GOPATH)/bin/smoketest get files '*' "./logs/{{ .Id }}/" ./logs - name: Upload artifacts uses: actions/upload-artifact@v4 if: always() with: name: logs-${{ github.run_id }} path: logs/ compression-level: 7 retention-days: 5 - name: Test Report Generation if: ${{ !cancelled() }} shell: bash run: | go install github.com/jstemmer/go-junit-report/v2@latest $(go env GOPATH)/bin/go-junit-report -in zititest/test.out -out test-report.xml - name: Test Summary uses: test-summary/action@v2 if: ${{ !cancelled() }} with: paths: | test-report.xml show: "fail, skip" fablab-smoketest-teardown: name: Teardown SmokeTest # ensure reasonable timeout-minutes on steps in this un-cancellable job if: always() runs-on: ubuntu-20.04 needs: [ fablab-smoketest ] steps: # allow time for investigation unless the workflow is cancelled or the smoketest succeeded or was skipped #- name: Sleep If Failed # if: needs.fablab-smoketest.result != 'success' && needs.fablab-smoketest.result != 'skipped' && needs.fablab-smoketest.result != 'cancelled' # shell: bash # run: | # sleep 30m # release cloud resources if the smoketest succeeded, failed, or was cancelled; unnecessary if skipped - name: Teardown Test Environment if: needs.fablab-smoketest.result != 'skipped' timeout-minutes: 30 env: FABLAB_PASSPHRASE: ${{ secrets.FABLAB_PASSPHRASE }} shell: bash run: | if aws s3api head-object \ --bucket ziti-smoketest-fablab-instances \ --key smoketest-${GITHUB_RUN_NUMBER}.tar.gz.gpg then aws s3 cp s3://ziti-smoketest-fablab-instances/smoketest-${GITHUB_RUN_NUMBER}.tar.gz.gpg . gpg --quiet --batch --yes --decrypt --passphrase=${FABLAB_PASSPHRASE} --output smoketest-${GITHUB_RUN_NUMBER}.tar.gz smoketest-${GITHUB_RUN_NUMBER}.tar.gz.gpg tar -xzf smoketest-${GITHUB_RUN_NUMBER}.tar.gz ./smoketest-${GITHUB_RUN_NUMBER}/smoketest import smoketest-${GITHUB_RUN_NUMBER} ./smoketest-${GITHUB_RUN_NUMBER}/smoketest dispose aws s3 rm s3://ziti-smoketest-fablab-instances/smoketest-${GITHUB_RUN_NUMBER}.tar.gz.gpg else echo "WARN: No instance archive found for smoketest-${GITHUB_RUN_NUMBER}.tar.gz.gpg" >&2 fi fablab-ha-smoketest: name: Fablab HA Smoketest # not applicable to forks. shouldn't run on release build if: false && github.repository_owner == 'openziti' && github.ref != 'refs/heads/main' runs-on: ubuntu-20.04 steps: - name: Git Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Install Ziti CI uses: openziti/ziti-ci@v1 - name: Build and Test env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ziti_ci_gpg_key: ${{ secrets.ZITI_CI_GPG_KEY }} ziti_ci_gpg_key_id: ${{ secrets.ZITI_CI_GPG_KEY_ID }} shell: bash run: | $(go env GOPATH)/bin/ziti-ci configure-git $(go env GOPATH)/bin/ziti-ci generate-build-info common/version/info_generated.go version pushd zititest && go install ./... && popd go install -tags=all,tests ./... - name: Create Test Environment shell: bash run: | echo "ZITI_ROOT=$(go env GOPATH)/bin" >> "$GITHUB_ENV" $(go env GOPATH)/bin/smoketest create -d smoketest-ha-${GITHUB_RUN_NUMBER} -n smoketest-ha-${GITHUB_RUN_NUMBER} -l ha=true,environment=gh-fablab-ha-smoketest,ziti_version=$($(go env GOPATH)/bin/ziti-ci -q get-current-version) $(go env GOPATH)/bin/smoketest up # - name: Test Ziti Command # shell: bash # run: | # echo "ZITI_ROOT=$(go env GOPATH)/bin" >> "$GITHUB_ENV" # pushd zititest && go test -timeout 30m -v ./tests/... 2>&1 | tee test.out && popd - name: Create fablab instance archive if: always() env: FABLAB_PASSPHRASE: ${{ secrets.FABLAB_PASSPHRASE }} shell: bash run: | cp $(go env GOPATH)/bin/smoketest smoketest-ha-${GITHUB_RUN_NUMBER} cp ~/.fablab/config.yml smoketest-ha-${GITHUB_RUN_NUMBER}/ tar --exclude *terraform-provider-aws* -czvf - smoketest-ha-${GITHUB_RUN_NUMBER}/ | gpg --symmetric --cipher-algo aes256 --batch --quiet --passphrase ${FABLAB_PASSPHRASE} -o smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz.gpg aws s3 cp ./smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz.gpg s3://ziti-smoketest-fablab-instances/ # - name: Test Report Generation # if: always() # shell: bash # run: | # go install github.com/jstemmer/go-junit-report/v2@latest #$(go env GOPATH)/bin/go-junit-report -in zititest/test.out -out test-report.xml # - name: Test Summary # uses: test-summary/action@v2 # with: # paths: | # test-report.xml # show: "fail, skip" # if: always() # END linux-build-steps fablab-ha-smoketest-teardown: name: Teardown HA SmokeTest if: always() runs-on: ubuntu-20.04 needs: [ fablab-ha-smoketest ] steps: # allow time for investigation unless the workflow is cancelled or the smoketest succeeded or was skipped - name: Sleep If Failed if: needs.fablab-ha-smoketest.result != 'success' && needs.fablab-ha-smoketest.result != 'skipped' && needs.fablab-ha-smoketest.result != 'cancelled' shell: bash run: | sleep 30m # release cloud resources if the smoketest succeeded, failed, or was cancelled; unnecessary if skipped - name: Teardown Test Environment if: needs.fablab-smoketest-ha.result != 'skipped' env: FABLAB_PASSPHRASE: ${{ secrets.FABLAB_PASSPHRASE }} shell: bash run: | if aws s3api head-object \ --bucket ziti-smoketest-fablab-instances \ --key smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz.gpg then aws s3 cp s3://ziti-smoketest-fablab-instances/smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz.gpg . gpg --quiet --batch --yes --decrypt --passphrase=${FABLAB_PASSPHRASE} --output smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz.gpg tar -xzf smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz ./smoketest-ha-${GITHUB_RUN_NUMBER}/smoketest import smoketest-ha-${GITHUB_RUN_NUMBER} ./smoketest-ha-${GITHUB_RUN_NUMBER}/smoketest dispose aws s3 rm s3://ziti-smoketest-fablab-instances/smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz.gpg else echo "WARN: No instance archive found for smoketest-ha-${GITHUB_RUN_NUMBER}.tar.gz.gpg" >&2 fi publish: name: Publish Binaries # - !cancelled() allows evaluating further conditional expressions even if # needed jobs were skipped if: ${{ !cancelled() && (needs.mac-os-build.result == 'success' || needs.mac-os-build.result == 'skipped') && (needs.windows-build.result == 'success' || needs.windows-build.result == 'skipped') && (needs.fablab-smoketest.result == 'success' || needs.fablab-smoketest.result == 'skipped') }} runs-on: ubuntu-20.04 needs: [ tests, linux-build, mac-os-build, windows-build, fablab-smoketest, fablab-ha-smoketest ] outputs: ZITI_VERSION: ${{ steps.get_version.outputs.ZITI_VERSION }} steps: - name: Git Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Go uses: actions/setup-go@v5 with: go-version-file: ./go.mod - name: Install Python uses: actions/setup-python@v5 with: python-version: '3.7' - name: Install Ziti CI uses: openziti/ziti-ci@v1 - name: Download linux release artifact uses: actions/download-artifact@v4 with: name: linux-release-${{ github.run_id }} path: release/ - name: Download darwin release artifact if: needs.mac-os-build.result == 'success' uses: actions/download-artifact@v4 with: name: darwin-release-${{ github.run_id }} path: release/ - name: Download windows release artifact if: needs.windows-build.result == 'success' uses: actions/download-artifact@v4 with: name: windows-release-${{ github.run_id }} path: release/ - name: List downloaded release artifacts shell: bash run: | ls -lAhR release/ - name: Restore execute filemode on macOS and Linux release artifacts before publishing shell: bash run: | find ./release \ -type f \ -print0 \ -path "./release/*/darwin/ziti" \ -o \ -path "./release/*/linux/ziti" \ | xargs -0 chmod -c +x - name: Publish GitHub Release # forks need to run this step with their own GPG key because ziti-ci creates the GH release if: env.ziti_ci_gpg_key_id != null && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ziti_ci_gpg_key: ${{ secrets.ZITI_CI_GPG_KEY }} ziti_ci_gpg_key_id: ${{ secrets.ZITI_CI_GPG_KEY_ID }} shell: bash run: | $(go env GOPATH)/bin/ziti-ci configure-git $(go env GOPATH)/bin/ziti-ci tag -v -f version $(go env GOPATH)/bin/ziti-ci publish-to-github --prerelease --archive-base "" # only ziti-ci computed version for release branches and {version}-{run_id} for non-release branches - name: Compute the Ziti Version String for CI Jobs id: get_version env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_REF: ${{ github.ref }} GITHUB_RUN_ID: ${{ github.run_id }} shell: bash run: | ZITI_VERSION="$($(go env GOPATH)/bin/ziti-ci -q get-current-version)" # drop the leading 'v', if any ZITI_VERSION=${ZITI_VERSION#v} if ! [[ "${ZITI_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then # fail the job because we could not obtain the current version from ziti-ci echo "ERROR: ZITI_VERSION=${ZITI_VERSION} is not a semver" exit 1 elif [[ "${GITHUB_REF}" =~ ^refs/heads/(release-v|main$) ]]; then # Set output parameters for release branches echo ZITI_VERSION="${ZITI_VERSION}" | tee -a $GITHUB_OUTPUT else # Append build / run number for non-release refs ZITI_VERSION="${ZITI_VERSION}-${GITHUB_RUN_ID}" echo ZITI_VERSION="${ZITI_VERSION}" | tee -a $GITHUB_OUTPUT fi call-publish-prerelease-docker-images: # - !cancelled() allows evaluating further conditional expressions even if # needed jobs were skipped if: ${{ !cancelled() && needs.publish.result == 'success' && github.ref == 'refs/heads/release-next' }} name: Publish Pre-Release Docker Images needs: publish uses: ./.github/workflows/publish-docker-images.yml secrets: inherit with: ziti-tag: release-next call-publish-release-docker-images: # - !cancelled() allows evaluating further conditional expressions even if # needed jobs were skipped if: ${{ !cancelled() && needs.publish.result == 'success' && ( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v') ) }} name: Publish Release Docker Images needs: publish uses: ./.github/workflows/publish-docker-images.yml secrets: inherit with: ziti-tag: ${{ needs.publish.outputs.ZITI_VERSION }} # call on release-next and release branches to publish linux packages to # "testing" and "release" package repos in Artifactory call-publish-linux-packages: # - !cancelled() allows evaluating further conditional expressions even if # needed jobs were skipped if: ${{ !cancelled() && needs.publish.result == 'success' && ( github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v') || github.ref == 'refs/heads/release-next' ) }} name: Publish Linux Packages needs: publish uses: ./.github/workflows/publish-linux-packages.yml secrets: inherit with: ziti-version: ${{ needs.publish.outputs.ZITI_VERSION }}