Skip to content

Update release verification workflow #15463

Update release verification workflow

Update release verification workflow #15463

Workflow file for this run

# ------------------------------------------------------------
# Copyright 2023 The Radius Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------------------------------------
name: Build and Test
on:
push:
branches:
- main
- release/*
tags:
- v*
pull_request:
branches:
- main
- features/*
- release/*
concurrency:
# Cancel the previously triggered build for only PR build.
group: build-${{ github.ref }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
env:
# Go version to install
GOVER: '^1.21'
GOPROXY: https://proxy.golang.org
# gotestsum version - see: https://github.com/gotestyourself/gotestsum
GOTESTSUMVERSION: 1.10.0
# Use radiusdev.azurecr.io for PR build. Otherwise, use radius.azurecr.io.
# TODO_LAUNCH: Remove this variable when we opensource the repo - https://github.com/radius-project/radius/issues/5892
DOCKER_REGISTRY: ${{ github.event_name == 'pull_request' && 'radiusdev.azurecr.io' || 'radius.azurecr.io' }}
# GitHub Actor for pushing images to GHCR
GHCR_ACTOR: rad-ci-bot
# Container registry url for GitHub container registry.
CONTAINER_REGISTRY: ${{ github.event_name == 'pull_request' && 'ghcr.io/radius-project/dev' || 'ghcr.io/radius-project/radius' }}
# Local file path to the release binaries.
RELEASE_PATH: ./release
jobs:
build:
name: Build ${{ matrix.target_os }}_${{ matrix.target_arch }} binaries
runs-on: ubuntu-latest
env:
GOOS: ${{ matrix.target_os }}
GOARCH: ${{ matrix.target_arch }}
GOPROXY: https://proxy.golang.org
strategy:
fail-fast: false
matrix:
include:
- target_os: linux
target_arch: arm
- target_os: linux
target_arch: arm64
- target_os: linux
target_arch: amd64
- target_os: windows
target_arch: amd64
- target_os: darwin
target_arch: amd64
- target_os: darwin
target_arch: arm64
steps:
- name: Check out repo
uses: actions/checkout@v3
- name: Set up Go ${{ env.GOVER }}
uses: actions/setup-go@v4
with:
go-version: ${{ env.GOVER }}
cache-dependency-path: go.sum
- name: Restore the previous coverage
uses: actions/cache/restore@v3
with:
path: ./dist/cache
key: radius-coverage-
- name: Parse release version and set environment variables
run: python ./.github/scripts/get_release_version.py
- name: Make build
run: make build
- name: Run make test (unit tests)
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
env:
GOTESTSUM_OPTS: '--junitfile ./dist/unit_test/results.xml'
GOTEST_OPTS: '-race -coverprofile ./dist/ut_coverage_orig.out'
run: |
go install gotest.tools/gotestsum@v${{ env.GOTESTSUMVERSION }}
make test
- name: Process Unit Test Results
uses: ./.github/actions/process-test-results
# Always is required here to make sure this target runs even when tests fail.
if: always() && matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
with:
test_group_name: 'Unit Tests'
artifact_name: 'unit_test_results'
result_directory: 'dist/unit_test/'
- name: Copy cli binaries to release (unix-like)
if: matrix.target_os != 'windows'
run: |
mkdir ${{ env.RELEASE_PATH }}
cp ./dist/${{ matrix.target_os}}_${{ matrix.target_arch}}/release/rad ${{ env.RELEASE_PATH }}/rad_${{ matrix.target_os}}_${{ matrix.target_arch}}
- name: Copy cli binaries to release (windows)
if: matrix.target_os == 'windows'
run: |
mkdir ${{ env.RELEASE_PATH }}
cp ./dist/${{ matrix.target_os}}_${{ matrix.target_arch}}/release/rad.exe ${{ env.RELEASE_PATH }}/rad_${{ matrix.target_os}}_${{ matrix.target_arch}}.exe
- name: Upload Release binaries
uses: actions/upload-artifact@v3
with:
name: rad_cli_release
path: ${{ env.RELEASE_PATH }}
# TOOD_LAUNCH: Remove this step when we opensource the repo - https://github.com/radius-project/radius/issues/5892
- name: Upload CLI binary
uses: actions/upload-artifact@v3
with:
name: rad_cli_${{ matrix.target_os}}_${{ matrix.target_arch}}
path: |
./dist/${{ matrix.target_os}}_${{ matrix.target_arch}}/release/rad
./dist/${{ matrix.target_os}}_${{ matrix.target_arch}}/release/rad.exe
- name: Generate unit-test coverage files
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
run: |
# Remove mock, generated files, and datamodels from original coverage output.
cat ./dist/ut_coverage_orig.out | grep -v "mock" | grep -v "zz_" | grep -v "armrpc/rpctest" | grep -v '/datamodel/[A-za-z0-9_]*.go' > $COVERAGE_FILE
# Generate reports.
$GO_TOOL_COVER -func=$COVERAGE_FILE -o ./dist/ut_coverage.txt
$GO_TOOL_COVER -html=$COVERAGE_FILE -o ./dist/ut_coverage.html
# Parse total coverage rate from report.
UT_COVERAGE=`cat ./dist/ut_coverage.txt | grep total: | grep -Eo '[0-9]+\.[0-9]+'`
echo "Test coverage : $UT_COVERAGE"
echo "ut_coverage=$UT_COVERAGE" >> $GITHUB_ENV
mkdir -p ./dist/cache
MAIN_COVERAGE=0
if [ -f "./dist/cache/ut_coverage.txt" ]; then
MAIN_COVERAGE=$(cat ./dist/cache/ut_coverage.txt | grep total: | grep -Eo '[0-9]+\.[0-9]+')
fi
echo "main_coverage=$MAIN_COVERAGE" >> $GITHUB_ENV
if (( $(echo "$UT_COVERAGE < $MAIN_COVERAGE" | bc -l) )) ; then
COLOR=red
else
COLOR=green
fi
DIFF_RATE=$(echo "$UT_COVERAGE-$MAIN_COVERAGE" | bc -l)
echo "diff_coverage=$DIFF_RATE" >> $GITHUB_ENV
echo "coverage_img=https://img.shields.io/badge/coverage-$UT_COVERAGE%25-$COLOR" >> $GITHUB_ENV
# copy coverage to cache
cp ./dist/ut_coverage.txt ./dist/cache/
env:
COVERAGE_FILE: ./dist/ut_coverage.out
GO_TOOL_COVER: go tool cover
- name: Upload unit-test coverage artifact
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux'
uses: actions/upload-artifact@v3
with:
name: unit_test_coverage
path: |
./dist/coverage_orig.out
./dist/ut_coverage.out
./dist/ut_coverage.txt
./dist/ut_coverage.html
- name: Add coverage result comment
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux' && github.event.pull_request && github.event.pull_request.head.repo.full_name == github.repository
uses: marocchino/sticky-pull-request-comment@v2
with:
header: testcov-${{ github.run_id }}
number: ${{ github.event.pull_request.number }}
hide: true
hide_classify: OUTDATED
message: |
![${{ env.ut_coverage }}](${{ env.coverage_img }})
For the detailed report, please go to `Checks tab`, click `Build and Test`, and then download `unit_test_coverage` artifact at the bottom of build page.
* Your PR branch coverage: ${{ env.ut_coverage }} %
* main branch coverage: ${{ env.main_coverage }} %
* diff coverage: ${{ env.diff_coverage }} %
> The coverage result does not include the functional test coverage.
- name: Save coverage (only main push)
uses: actions/cache/save@v3
if: matrix.target_arch == 'amd64' && matrix.target_os == 'linux' && github.ref == 'refs/heads/main'
with:
path: ./dist/cache
key: radius-coverage-${{ github.sha }}-${{ github.run_number }}
# Logic here:
# - always do a docker build for validation
# - tag the image as latest and with a version if the trigger was a tag
# - tag the image with the PR version if the trigger was a PR
# - push the image for pushes to master, or to a tag
# TODO_LAUNCH: Remove 'image' job when we opensource the repo - https://github.com/radius-project/radius/issues/5892
images:
name: Container image build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Parse release version and set environment variables
run: python ./.github/scripts/get_release_version.py
- name: Set up Go ${{ env.GOVER }}
uses: actions/setup-go@v4
with:
go-version: ${{ env.GOVER }}
- uses: azure/docker-login@v1
with:
login-server: ${{ env.DOCKER_REGISTRY }}
username: '${{ secrets.DOCKER_USERNAME }}'
password: '${{ secrets.DOCKER_PASSWORD }}'
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
platforms: linux/amd64,linux/arm64,linux/arm/v7
- name: Push container images (latest)
run: |
make docker-test-image-build && make docker-test-image-push
make docker-multi-arch-push
if: (github.ref == 'refs/heads/main') # push image to latest on merge to main
env:
DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }}
DOCKER_TAG_VERSION: latest
- name: Push container images (PR)
run: |
make docker-test-image-build && make docker-test-image-push
make docker-multi-arch-push
if: github.event_name == 'pull_request'
env:
DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }}
DOCKER_TAG_VERSION: ${{ env.REL_VERSION }} # includes PR number
- name: Push container images (release)
run: |
make docker-test-image-build && make docker-test-image-push
make docker-multi-arch-push
if: startsWith(github.ref, 'refs/tags/v') # push image on tag
env:
DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }}
DOCKER_TAG_VERSION: ${{ env.REL_CHANNEL }}
# publish_image is building and publishing images to GHCR.
publish_images:
name: Build and publish container images
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Parse release version and set environment variables
run: python ./.github/scripts/get_release_version.py
- name: Set up Go ${{ env.GOVER }}
uses: actions/setup-go@v4
with:
go-version: ${{ env.GOVER }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ env.GHCR_ACTOR }}
password: ${{ secrets.GH_RAD_CI_BOT_PAT }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
platforms: linux/amd64,linux/arm64,linux/arm/v7
- name: Push container images (latest)
run: |
make docker-test-image-build && make docker-test-image-push
make docker-multi-arch-push
if: (github.ref == 'refs/heads/main') # push image to latest on merge to main
env:
DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }}
DOCKER_TAG_VERSION: latest
- name: Push container images (PR)
run: |
make docker-test-image-build && make docker-test-image-push
make docker-multi-arch-push
if: github.event_name == 'pull_request'
env:
DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }}
DOCKER_TAG_VERSION: ${{ env.REL_VERSION }} # includes PR number
- name: Push container images (release)
run: |
make docker-test-image-build && make docker-test-image-push
make docker-multi-arch-push
if: startsWith(github.ref, 'refs/tags/v') # push image on tag
env:
DOCKER_REGISTRY: ${{ env.CONTAINER_REGISTRY }}
DOCKER_TAG_VERSION: ${{ env.REL_CHANNEL }}
helm:
name: Helm chart build
needs: ['images', 'publish_images']
runs-on: ubuntu-latest
env:
ARTIFACT_DIR: ./dist/Charts
HELM_PACKAGE_DIR: helm
HELM_CHARTS_DIR: deploy/Chart
OCI_REGISTRY: ghcr.io
OCI_REPOSITORY: ${{ startsWith(github.ref, 'refs/tags/v') && 'radius-project/helm-chart' || 'radius-project/dev/helm-chart' }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install helm
uses: Azure/setup-helm@v3
with:
version: 'v3.11.1'
- name: Setup Azure CLI
run: curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
- name: Parse release version and set environment variables
run: python ./.github/scripts/get_release_version.py
- name: Run Helm linter
run: |
helm lint ${{ env.HELM_CHARTS_DIR }}
- name: Package Helm chart
run: |
mkdir -p ${{ env.ARTIFACT_DIR }}/${{ env.HELM_PACKAGE_DIR }}
helm package ${{ env.HELM_CHARTS_DIR }} --version ${{ env.CHART_VERSION }} --app-version ${{ env.REL_VERSION }} --destination ${{ env.ARTIFACT_DIR }}/${{ env.HELM_PACKAGE_DIR }}
- name: az CLI login
run: |
az login --service-principal \
--username ${{ secrets.AZURE_SP_TESTS_APPID }} \
--password ${{ secrets.AZURE_SP_TESTS_PASSWORD }} \
--tenant ${{ secrets.AZURE_SP_TESTS_TENANTID }}
- name: Push helm chart to ACR
run: |
az acr helm push --name radius ${{ env.ARTIFACT_DIR }}/${{ env.HELM_PACKAGE_DIR }}/radius-${{ env.CHART_VERSION }}.tgz --force
- name: Push helm chart to GHCR
run: |
echo ${{ secrets.GITHUB_TOKEN }} | helm registry login -u ${{ github.actor }} --password-stdin ${{ env.OCI_REGISTRY }}
helm push ${{ env.ARTIFACT_DIR }}/${{ env.HELM_PACKAGE_DIR }}/radius-${{ env.CHART_VERSION }}.tgz oci://${{ env.OCI_REGISTRY }}/${{ env.OCI_REPOSITORY }}
publish_release:
name: Publish GitHub Release
needs: [ 'build' ]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Parse release version and set environment variables
run: python ./.github/scripts/get_release_version.py
- name: Download release artifacts
uses: actions/download-artifact@v3
with:
name: rad_cli_release
path: ${{ env.RELEASE_PATH }}
- name: generate checksum files
run: cd ${{ env.RELEASE_PATH }} && for i in *; do sha256sum -b $i > "$i.sha256"; done && cd -
- name: Create GitHub RC Release (pre-release and auto-generate release notes)
if: ${{ contains(env.REL_VERSION, 'rc') }}
run: |
gh release create v${{ env.REL_VERSION }} \
${{ env.RELEASE_PATH }}/* \
--title "Project Radius v${{ env.REL_VERSION }}" \
--generate-notes \
--verify-tag \
--prerelease
env:
GITHUB_TOKEN: ${{ secrets.GH_RAD_CI_BOT_PAT }}
- name: Create GitHub Official Release
if: ${{ !contains(env.REL_VERSION, 'rc') }}
run: |
gh release create v${{ env.REL_VERSION }} \
${{ env.RELEASE_PATH }}/* \
--title "Project Radius v${{ env.REL_VERSION }}" \
--notes-file docs/release-notes/v${{ env.REL_VERSION }}.md \
--verify-tag
env:
GITHUB_TOKEN: ${{ secrets.GH_RAD_CI_BOT_PAT }}
# TODO_LAUNCH: Remove this job once we opensource - https://github.com/radius-project/radius/issues/5892
publish:
name: Publish rad CLI binaries
needs: [ 'build' ]
runs-on: ubuntu-latest
if: (github.ref == 'refs/heads/main') || startsWith(github.ref, 'refs/tags/v') # upload on push to main or tag
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Parse release version and set environment variables
run: python ./.github/scripts/get_release_version.py
- name: Download release artifacts
uses: actions/download-artifact@v3
with:
name: rad_cli_darwin_arm64
path: rad_cli_darwin_arm64
- name: Download release artifacts
uses: actions/download-artifact@v3
with:
name: rad_cli_darwin_amd64
path: rad_cli_darwin_amd64
- name: Download release artifacts
uses: actions/download-artifact@v3
with:
name: rad_cli_linux_arm
path: rad_cli_linux_arm
- name: Download release artifacts
uses: actions/download-artifact@v3
with:
name: rad_cli_linux_arm64
path: rad_cli_linux_arm64
- name: Download release artifacts
uses: actions/download-artifact@v3
with:
name: rad_cli_linux_amd64
path: rad_cli_linux_amd64
- name: Download release artifacts
uses: actions/download-artifact@v3
with:
name: rad_cli_windows_amd64
path: rad_cli_windows_amd64
- uses: bacongobbler/[email protected]
with:
source_dir: rad_cli_darwin_amd64
container_name: 'tools'
connection_string: ${{ secrets.ASSETS_STORAGE_CONNECTION_STRING }}
overwrite: 'true'
extra_args: '--destination-path rad/${{ env.REL_CHANNEL }}/macos-x64/ --pattern rad --timeout 300'
- uses: bacongobbler/[email protected]
with:
source_dir: rad_cli_darwin_arm64
container_name: 'tools'
connection_string: ${{ secrets.ASSETS_STORAGE_CONNECTION_STRING }}
overwrite: 'true'
extra_args: '--destination-path rad/${{ env.REL_CHANNEL }}/macos-arm64/ --pattern rad --timeout 300'
- uses: bacongobbler/[email protected]
with:
source_dir: rad_cli_linux_amd64
container_name: 'tools'
connection_string: ${{ secrets.ASSETS_STORAGE_CONNECTION_STRING }}
overwrite: 'true'
extra_args: '--destination-path rad/${{ env.REL_CHANNEL }}/linux-x64/ --pattern rad --timeout 300'
- uses: bacongobbler/[email protected]
with:
source_dir: rad_cli_linux_arm
container_name: 'tools'
connection_string: ${{ secrets.ASSETS_STORAGE_CONNECTION_STRING }}
overwrite: 'true'
extra_args: '--destination-path rad/${{ env.REL_CHANNEL }}/linux-arm/ --pattern rad --timeout 300'
- uses: bacongobbler/[email protected]
with:
source_dir: rad_cli_linux_arm64
container_name: 'tools'
connection_string: ${{ secrets.ASSETS_STORAGE_CONNECTION_STRING }}
overwrite: 'true'
extra_args: '--destination-path rad/${{ env.REL_CHANNEL }}/linux-arm64/ --pattern rad --timeout 300'
- uses: bacongobbler/[email protected]
with:
source_dir: rad_cli_windows_amd64
container_name: 'tools'
connection_string: ${{ secrets.ASSETS_STORAGE_CONNECTION_STRING }}
overwrite: 'true'
extra_args: '--destination-path rad/${{ env.REL_CHANNEL }}/windows-x64/ --pattern rad.exe --timeout 300'
delete_artifacts:
name: Delete artifacts
needs: [ 'build', 'publish' ]
if: ${{ always() && !contains(needs.build.result, 'failure') }}
runs-on: ubuntu-latest
steps:
- name: Delete release artifacts
uses: geekyeggo/delete-artifact@v1
with:
name: |
rad_cli_windows_amd64
rad_cli_linux_amd64
rad_cli_darwin_amd64
rad_cli_linux_arm
rad_cli_darwin_arm64
rad_cli_linux_arm64
failOnError: false