Skip to content

Refactor new command #4241

Refactor new command

Refactor new command #4241

Workflow file for this run

name: Build
on:
workflow_dispatch:
inputs:
k6_version:
description: 'The version of the release, it must use the semantic versioning format with the v prefix. It is a development release so it is suggested to append a build metadata (e.g. v0.38.0-dev).'
required: true
go_version:
description: 'Go version for building binaries'
default: '1.x'
required: true
push:
branches:
- master
tags:
- v*
pull_request:
defaults:
run:
shell: bash
env:
APP_NAME: "k6"
DOCKER_IMAGE_ID: "grafana/k6"
GHCR_IMAGE_ID: ${{ github.repository }}
DEFAULT_GO_VERSION: "1.23.x"
jobs:
configure:
runs-on: ubuntu-latest
outputs:
k6_version: ${{ steps.get_k6_version.outputs.k6_version }}
go_version: ${{ steps.get_go_version.outputs.go_version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get the k6 version
id: get_k6_version
run: |
set -x # Show exactly what commands are executed
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] && [[ "${{ github.event.inputs.k6_version }}" != "" ]]; then
VERSION="${{ github.event.inputs.k6_version }}"
echo "Building custom dev build with version '${VERSION}' from manual workflow_dispatch..."
elif [[ "${GITHUB_REF}" =~ ^refs/tags/v.+$ ]]; then
VERSION="${GITHUB_REF##*/}"
echo "Building real version tag '${GITHUB_REF}', parsed '${VERSION}' as the actual version..."
else
VERSION="$(git describe --tags --always --long --dirty)"
echo "Building a non-version ref '${GITHUB_REF}', use '${VERSION}' as the version instead..."
fi
echo "VERSION=${VERSION}"
echo "k6_version=${VERSION}" >> $GITHUB_OUTPUT
- name: Get the used Go version
id: get_go_version
run: |
set -x # Show exactly what commands are executed
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] && [[ "${{ github.event.inputs.go_version }}" != "" ]]; then
GO_VERSION="${{ github.event.inputs.go_version }}"
echo "Using custom Go version '${GO_VERSION}' from manual workflow_dispatch..."
else
GO_VERSION="${DEFAULT_GO_VERSION}"
echo "Using the default Go version '${GO_VERSION}'..."
fi
echo "GO_VERSION=${GO_VERSION}"
echo "go_version=${GO_VERSION}" >> $GITHUB_OUTPUT
build:
runs-on: ubuntu-latest
needs: [configure]
env:
VERSION: ${{ needs.configure.outputs.k6_version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: ${{ needs.configure.outputs.go_version }}
check-latest: true
- name: Install nfpm (dep and rpm package builder)
run: |
go install github.com/goreleaser/nfpm/v2/cmd/[email protected]
- name: Install goversioninfo (.syso file creator)
run: |
go install github.com/josephspurrier/goversioninfo/cmd/[email protected]
- name: Generate Windows binary metadata (.syso files)
run: |
IFS=. read -a version_parts <<< "${VERSION#v}"
IFS=- read -a version_patch <<< "${version_parts[2]}"
# Need a blank versioninfo.json for the CLI overrides to work.
echo '{}' > versioninfo.json
set -x
goversioninfo -64 \
-platform-specific=true \
-charset="1200" \
-company="Raintank Inc. d.b.a. Grafana Labs" \
-copyright="© Raintank Inc. d.b.a. Grafana Labs. Licensed under AGPL." \
-description="A modern load testing tool, using Go and JavaScript" \
-icon=packaging/k6.ico \
-internal-name="k6" \
-original-name="k6.exe" \
-product-name="k6" \
-translation="0x0409" \
-ver-major="${version_parts[0]}" \
-ver-minor="${version_parts[1]}" \
-ver-patch="${version_patch[0]}" \
-special-build=$(IFS='-'; echo "${version_patch[*]:1}";) \
-product-version="${VERSION#v}"
set +x
ls -lah | grep -i syso
- name: Build
run: |
go version
./build-release.sh "dist" "${VERSION}"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: binaries
path: dist/
retention-days: 7
build-docker:
runs-on: ubuntu-latest
needs: [configure]
env:
VERSION: ${{ needs.configure.outputs.k6_version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build
run: |
docker buildx create \
--name multibuilder \
--platform linux/amd64,linux/arm64 \
--bootstrap --use
docker buildx build \
--target release \
--platform linux/amd64,linux/arm64 \
-t $DOCKER_IMAGE_ID .
- name: Check
run: |
docker buildx build --load -t $DOCKER_IMAGE_ID .
# Assert that simple cases works for the new built image
docker run $DOCKER_IMAGE_ID version
docker run $DOCKER_IMAGE_ID --help
docker run $DOCKER_IMAGE_ID help
docker run $DOCKER_IMAGE_ID run --help
docker run $DOCKER_IMAGE_ID inspect --help
docker run $DOCKER_IMAGE_ID status --help
docker run $DOCKER_IMAGE_ID stats --help
docker run $DOCKER_IMAGE_ID scale --help
docker run $DOCKER_IMAGE_ID pause --help
docker run $DOCKER_IMAGE_ID resume --help
- name: Log into registries (ghcr.io and Docker Hub)
if: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v') }}
run: |
# Log into GitHub Container Registry
echo "${{ secrets.GITHUB_TOKEN }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin
# Log into Docker Hub Registry
echo "${{ secrets.DOCKER_PASS }}" | docker login -u "${{ secrets.DOCKER_USER }}" --password-stdin
- name: Publish k6:master images
if: ${{ github.ref == 'refs/heads/master' }}
run: |
echo "Publish $GHCR_IMAGE_ID:master* images"
docker buildx build --push \
--target release \
--platform linux/amd64,linux/arm64 \
-t $DOCKER_IMAGE_ID:master \
-t ghcr.io/$GHCR_IMAGE_ID:master .
docker buildx build --push \
--target with-browser \
--platform linux/amd64,linux/arm64 \
-t $DOCKER_IMAGE_ID:master-with-browser \
-t ghcr.io/$GHCR_IMAGE_ID:master-with-browser .
- name: Publish tagged version images
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
run: |
VERSION="${VERSION#v}"
echo "Publish $GHCR_IMAGE_ID:$VERSION images"
docker buildx build --push \
--target release \
--platform linux/amd64,linux/arm64 \
-t $DOCKER_IMAGE_ID:$VERSION \
-t ghcr.io/$GHCR_IMAGE_ID:$VERSION .
docker buildx build --push \
--target with-browser \
--platform linux/amd64,linux/arm64 \
-t $DOCKER_IMAGE_ID:$VERSION-with-browser \
-t ghcr.io/$GHCR_IMAGE_ID:$VERSION-with-browser .
# We also want to tag the latest stable version as latest
if [[ ! "$VERSION" =~ (RC|rc) ]]; then
echo "Publish $GHCR_IMAGE_ID:latest"
docker buildx build --push \
--target release \
--platform linux/amd64,linux/arm64 \
-t $DOCKER_IMAGE_ID:latest \
-t ghcr.io/$GHCR_IMAGE_ID:latest .
docker buildx build --push \
--target with-browser \
--platform linux/amd64,linux/arm64 \
-t $DOCKER_IMAGE_ID:latest-with-browser \
-t ghcr.io/$GHCR_IMAGE_ID:latest-with-browser .
fi
package-windows:
runs-on: windows-latest
defaults:
run:
shell: pwsh
needs: [configure, build]
env:
VERSION: ${{ needs.configure.outputs.k6_version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install pandoc
uses: crazy-max/ghaction-chocolatey@0e015857dd851f84fcb7fb53380eb5c4c8202333 # v3.0.0
with:
args: install -y pandoc
- name: Install wix tools
run: |
curl -Lso wix311-binaries.zip https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip
Expand-Archive -Path .\wix311-binaries.zip -DestinationPath .\wix311\
echo "$pwd\wix311" | Out-File -FilePath $env:GITHUB_PATH -Append
- name: Download binaries
uses: actions/download-artifact@v4
with:
name: binaries
path: dist
- name: Unzip Windows binary
run: |
Expand-Archive -Path ".\dist\k6-$env:VERSION-windows-amd64.zip" -DestinationPath .\packaging\
move .\packaging\k6-$env:VERSION-windows-amd64\k6.exe .\packaging\
rmdir .\packaging\k6-$env:VERSION-windows-amd64\
- name: Add signtool to PATH
run: echo "${env:ProgramFiles(x86)}\Windows Kits\10\bin\10.0.17763.0\x64" | Out-File -FilePath $env:GITHUB_PATH -Append
- name: Create the MSI package
run: |
$env:VERSION = $env:VERSION -replace 'v(\d+\.\d+\.\d+).*','$1'
pandoc -s -f markdown -t rtf -o packaging\LICENSE.rtf LICENSE.md
cd .\packaging
candle.exe -arch x64 "-dVERSION=$env:VERSION" k6.wxs
light.exe -ext WixUIExtension k6.wixobj
- name: Sign Windows binary and .msi package
# GH secrets are unavaileble when building from project forks, so this
# will fail for external PRs, even if we wanted to do it. And we don't.
# We are only going to sign packages that are built from master or a
# version tag, or manually triggered dev builds, so we have enough
# assurance that package signing works, but don't sign every PR build.
if: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' }}
run: |
# Convert base64 certificate to PFX
$bytes = [Convert]::FromBase64String("${{ secrets.WIN_SIGN_CERT }}")
[IO.File]::WriteAllBytes("k6.pfx", $bytes)
# Sign the Windows binary
signtool sign /f k6.pfx /p "${{ secrets.WIN_SIGN_PASS }}" /tr "http://timestamp.digicert.com" /td sha256 /fd sha256 "packaging\k6.exe"
# Sign the MSI package
signtool sign /f k6.pfx /p "${{ secrets.WIN_SIGN_PASS }}" /tr "http://timestamp.digicert.com" /td sha256 /fd sha256 "packaging\k6.msi"
# Cleanup signing artifacts
del k6.pfx
- name: Rename MSI package
# To keep it consistent with the other artifacts
run: move "packaging\k6.msi" "packaging\k6-$env:VERSION-windows-amd64.msi"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: binaries-windows
path: |
packaging/k6-*.msi
retention-days: 7
publish-github:
runs-on: ubuntu-latest
needs: [configure, build, package-windows]
if: ${{ startsWith(github.ref, 'refs/tags/v') && github.event_name != 'workflow_dispatch' }}
env:
VERSION: ${{ needs.configure.outputs.k6_version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download binaries
uses: actions/download-artifact@v4
with:
name: binaries
path: dist
- name: Download Windows binaries
uses: actions/download-artifact@v4
with:
name: binaries-windows
path: dist
- name: Generate checksum file
run: cd dist && sha256sum * > "k6-${VERSION}-checksums.txt"
- name: Anchore SBOM Action
continue-on-error: true
uses: anchore/sbom-action@9fece9e20048ca9590af301449208b2b8861333b # v0.15.9
with:
artifact-name: k6-${{ env.VERSION }}-spdx.json
upload-release-assets: false
output-file: dist/k6-${{ env.VERSION }}-spdx.json
- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -x
assets=()
for asset in ./dist/*; do
assets+=("$asset")
done
gh release create "$VERSION" "${assets[@]}" --target "$GITHUB_SHA" -F "./release notes/${VERSION}.md"
publish-packages:
runs-on: ubuntu-latest
needs: [configure, build, package-windows]
if: ${{ startsWith(github.ref, 'refs/tags/v') && github.event_name != 'workflow_dispatch' }}
env:
VERSION: ${{ needs.configure.outputs.k6_version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download binaries
uses: actions/download-artifact@v4
with:
name: binaries
path: dist
- name: Download Windows binaries
uses: actions/download-artifact@v4
with:
name: binaries-windows
path: dist
- name: Rename binaries
# To be consistent with the filenames used in dl.k6.io
run: |
mv "dist/k6-$VERSION-windows-amd64.msi" "dist/k6-$VERSION-amd64.msi"
mv "dist/k6-$VERSION-linux-amd64.rpm" "dist/k6-$VERSION-amd64.rpm"
mv "dist/k6-$VERSION-linux-amd64.deb" "dist/k6-$VERSION-amd64.deb"
- name: Setup docker compose environment
run: |
cat > packaging/.env <<EOF
AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION=us-east-1
AWS_CF_DISTRIBUTION="${{ secrets.AWS_CF_DISTRIBUTION }}"
PGP_SIGN_KEY_PASSPHRASE=${{ secrets.PGP_SIGN_KEY_PASSPHRASE }}
EOF
echo "${{ secrets.PGP_SIGN_KEY }}" > packaging/sign-key.gpg
- name: Publish packages
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin
cd packaging
docker compose pull packager
docker compose run --rm packager