Files
podman/.github/workflows/release.yml
Daniel Hast 925107a0c9 ci: use env vars to avoid template expansion in code contexts
Template expansions are not aware of shell script syntax, and therefore
can potentially result in code injection vulnerabilities when used in
code contexts: https://docs.zizmor.sh/audits/#template-injection

To avoid this, instead use environment variables to safely store the
values of the template expansions.

Also (in the process of doing the above) added double-quotes around a
some instances of variable expansions in shell scripts, which is
necessary to avoid unintended shell splitting and globbing. (I didn't
see any instances where this was actually likely to result in erroneous
behavior, but it's good practice and makes shell scripts more robust.)

Signed-off-by: Daniel Hast <hast.daniel@protonmail.com>
(cherry picked from commit 67c050bb8e)
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
2026-06-08 15:22:46 +02:00

407 lines
14 KiB
YAML

name: Release
on:
push:
tags:
- '*'
workflow_dispatch:
inputs:
version:
description: 'Release version to build and upload (e.g. "v9.8.7")'
required: true
buildonly:
description: 'Build only: Do not create release'
default: "true" # 'choice' type requires string value
type: choice
options:
- "true" # Must be quoted string, boolean value not supported.
- "false"
jobs:
check:
name: Check
runs-on: ubuntu-latest
steps:
- name: Determine Version
id: getversion
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
if [[ -z "${INPUT_VERSION}" ]]
then
VERSION=${GITHUB_REF_NAME}
else
VERSION=${INPUT_VERSION}
fi
if ! grep -Eq 'v[0-9]+(\.[0-9]+(\.[0-9]+(-.+)?)?)?$' <<<"$VERSION"
then
echo "Unable to parse release version '$VERSION' from github event JSON, or workflow 'version' input."
exit 1
fi
if grep -Eq '.+-dev$' <<<"$VERSION"
then
echo "Refusing to process a "-dev" version '$VERSION'"
exit 1
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "::notice::Building $VERSION"
- name: Determine release
id: buildonly
env:
INPUT_BUILDONLY: ${{ inputs.buildonly }}
run: |
# The 'tag' trigger will not have a 'buildonly' input set. Handle
# this case in a readable/maintainable way.
if [[ -z "${INPUT_BUILDONLY}" ]]
then
BUILDONLY=false
else
BUILDONLY=${INPUT_BUILDONLY}
fi
echo "buildonly=$BUILDONLY" >> $GITHUB_OUTPUT
echo "::notice::This will be build-only: $BUILDONLY"
outputs:
version: ${{ steps.getversion.outputs.version }}
buildonly: ${{ steps.buildonly.outputs.buildonly }}
build-artifacts:
name: Build Artifacts
runs-on: ubuntu-latest
needs: check
steps:
- name: Checkout Version
uses: actions/checkout@v5
with:
ref: ${{needs.check.outputs.version}}
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Set up pandoc
run: |
sudo apt-get install -y pandoc
- name: Build Artifacts
run: |
make release-artifacts
- name: Upload to Actions as artifact
uses: actions/upload-artifact@v4
with:
name: release-artifacts
path: release/*
mac-pkg:
name: Build MacOS pkginstaller
needs: check
runs-on: macos-latest
env:
APPLICATION_CERTIFICATE: ${{ secrets.MACOS_APPLICATION_CERT }}
CODESIGN_IDENTITY: ${{ secrets.MACOS_APPLICATION_IDENTITY }}
INSTALLER_CERTIFICATE: ${{ secrets.MACOS_INSTALLER_CERT }}
PRODUCTSIGN_IDENTITY: ${{ secrets.MACOS_INSTALLER_IDENTITY }}
CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }}
NOTARIZE_TEAM: ${{ secrets.MACOS_NOTARIZATION_TEAM_ID }}
NOTARIZE_USERNAME: ${{ secrets.MACOS_NOTARIZATION_APPLE_ID }}
NOTARIZE_PASSWORD: ${{ secrets.MACOS_NOTARIZATION_PWD }}
KEYCHAIN_PWD: ${{ secrets.MACOS_CI_KEYCHAIN_PWD }}
steps:
- name: Checkout Version
uses: actions/checkout@v5
with:
ref: ${{needs.check.outputs.version}}
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Create Keychain
run: |
echo $APPLICATION_CERTIFICATE | base64 --decode -o appcert.p12
echo $INSTALLER_CERTIFICATE | base64 --decode -o instcert.p12
security create-keychain -p "$KEYCHAIN_PWD" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "$KEYCHAIN_PWD" build.keychain
security import appcert.p12 -k build.keychain -P "$CERTIFICATE_PWD" -T /usr/bin/codesign
security import instcert.p12 -k build.keychain -P "$CERTIFICATE_PWD" -T /usr/bin/productsign
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PWD" build.keychain &> /dev/null
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$NOTARIZE_USERNAME" --team-id "$NOTARIZE_TEAM" --password "$NOTARIZE_PASSWORD" &> /dev/null
- name: Build and Sign ARM
working-directory: contrib/pkginstaller
run: |
make ARCH=aarch64 notarize &> /dev/null
- name: Build and Sign AMD
working-directory: contrib/pkginstaller
run: |
make ARCH=amd64 notarize &> /dev/null
- name: Build and Sign Universal
working-directory: contrib/pkginstaller
run: |
make ARCH=universal notarize &> /dev/null
- name: Artifact
uses: actions/upload-artifact@v4
with:
name: mac-installers
path: |
contrib/pkginstaller/out/podman-installer-macos-*.pkg
windows-installer:
name: Build Windows Installer
strategy:
matrix:
arch: [amd64, arm64]
runs-on: windows-latest
needs: [check, build-artifacts]
env:
FETCH_BASE_URL: ${{ github.server_url }}/${{ github.repository }}
steps:
- name: Determine version
id: getversion
env:
VERSION: ${{needs.check.outputs.version}}
run: |
$version = "${env:VERSION}"
if ($version[0] -eq "v") {
$version = $version.Substring(1)
}
Write-Output "version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
- name: Checkout Podman
uses: actions/checkout@v5
- name: Download Windows zip artifact
uses: actions/download-artifact@v6
with:
name: release-artifacts
path: ${{ github.workspace }}\release-artifacts
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: stable
- name: Set up WiX
run: dotnet tool install --global wix --version 5.0.2
- name: Setup Signature Tooling
env:
AZ_CERT_NAME: ${{ secrets.AZ_CERT_NAME }}
AZ_VAULT_ID: ${{ secrets.AZ_VAULT_ID }}
AZ_APP_ID: ${{ secrets.AZ_APP_ID }}
AZ_TENANT_ID: ${{ secrets.AZ_TENANT_ID }}
AZ_CLIENT_SECRET: ${{ secrets.AZ_CLIENT_SECRET }}
run: |
dotnet tool install --global AzureSignTool --version 3.0.0
echo "CERT_NAME=${env:AZ_CERT_NAME}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "VAULT_ID=${env:AZ_VAULT_ID}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "APP_ID=${env:AZ_APP_ID}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "TENANT_ID=${env:AZ_TENANT_ID}" | Out-File -FilePath $env:GITHUB_ENV -Append
echo "CLIENT_SECRET=${env:AZ_CLIENT_SECRET}" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: Pandoc Setup
uses: r-lib/actions/setup-pandoc@v2
with:
pandoc-version: '3.1.11'
# Note: Windows assigns a UUID to the installer at build time, it's assumed
# by windows that one release version == one UUID (always). Breaking this assumption
# has some rather nasty side-effects in windows, such as possibly breaking 'uninstall'
# functionality. We should avoid clobbering or re-building windows installers in most cases,
# For build-only, the .exe is saved in the workflow artifacts for a human
# to judge.
- name: Build the MSI
id: build
env:
PODMAN_ARCH: ${{ matrix.arch }}
VERSION: ${{ steps.getversion.outputs.version }}
run: |
contrib\win-installer\build.ps1 `
-Version "${env:VERSION}" `
-LocalReleaseDirPath "${env:GITHUB_WORKSPACE}\release-artifacts" `
-Architecture "${env:PODMAN_ARCH}"
Exit $LASTEXITCODE
- name: Build the bundle (legacy)
id: build-legacy
env:
PODMAN_ARCH: ${{ matrix.arch }}
VERSION: ${{ steps.getversion.outputs.version }}
run: |
Push-Location contrib\win-installer-legacy
.\build.ps1 "${env:VERSION}" prod "${env:GITHUB_WORKSPACE}\release-artifacts"
$code = $LASTEXITCODE
if ($code -eq 2) {
Write-Output "artifact-missing=true" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
Pop-Location
Exit 0
}
Pop-Location
Exit $code
- name: Display structure of built files
run: |
Push-Location contrib\win-installer
Get-ChildItem
Pop-Location
Push-Location contrib\win-installer-legacy
Get-ChildItem
Pop-Location
- name: Rename the MSI
env:
PODMAN_ARCH: ${{ matrix.arch }}
VERSION: ${{ steps.getversion.outputs.version }}
run: |
Push-Location contrib\win-installer
Copy-Item -Path "podman-${env:VERSION}.msi" -Destination "podman-installer-windows-${env:PODMAN_ARCH}.msi"
Pop-Location
- name: Rename the bundle (legacy)
env:
PODMAN_ARCH: ${{ matrix.arch }}
VERSION: ${{ steps.getversion.outputs.version }}
run: |
Push-Location contrib\win-installer-legacy
Copy-Item -Path "podman-${env:VERSION}-setup.exe" -Destination "podman-installer-windows-${env:PODMAN_ARCH}.exe"
Pop-Location
- name: Upload the MSI
uses: actions/upload-artifact@v4
with:
name: win-msi-${{ matrix.arch }}
path: |
.\contrib\win-installer\podman-installer-windows-${{ matrix.arch }}.msi
- name: Upload the bundle (legacy)
uses: actions/upload-artifact@v4
with:
name: win-installer-${{ matrix.arch }}
path: |
.\contrib\win-installer-legacy\podman-installer-windows-${{ matrix.arch }}.exe
# For backwards compatibility, we also upload the amd64 windows
# installer using the old name
- name: Upload the bundle with the old name (legacy)
uses: actions/upload-artifact@v4
if: ${{ matrix.arch == 'amd64' }}
with:
name: win-installer
path: |
.\contrib\win-installer-legacy\podman-${{steps.getversion.outputs.version}}-setup.exe
release:
name: Create Release
runs-on: ubuntu-latest
if: needs.check.outputs.buildonly == 'false'
needs: [check, build-artifacts, mac-pkg, windows-installer]
permissions:
contents: write
env:
VERSION: ${{needs.check.outputs.version}}
steps:
- name: Checkout Version
uses: actions/checkout@v5
with:
ref: ${{needs.check.outputs.version}}
- name: Get release notes
run: |
ver="$(echo "$VERSION" | sed -e "s/^v//" -e "s/-rc.*//")"
releasenotes="$VERSION-release-notes.md"
awk -v ver=$ver '/^## / { if (p) { exit }; if ($2 == ver) { p=1; next } } p' RELEASE_NOTES.md > $releasenotes
if [[ -z $(grep '[^[:space:]]' $releasenotes) ]]; then
if [[ $VERSION != *-rc* ]]; then
echo "::notice:: Release does not have release notes"
exit 1
else
echo "This is a release candidate of Podman v$ver. Full release notes will be available with a later RC." > $releasenotes
fi
fi
- name: Display release notes
run: cat $VERSION-release-notes.md
- name: Download all artifacts
uses: actions/download-artifact@v5
- name: Show artifacts
run: |
mv win-installer/* release-artifacts
mv mac-installers/* release-artifacts
mv win-installer-amd64/* release-artifacts
mv win-installer-arm64/* release-artifacts
mv win-msi-amd64/* release-artifacts
mv win-msi-arm64/* release-artifacts
pushd release-artifacts
sha256sum * > shasums
popd
- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
title=$VERSION
if [[ $VERSION == *-rc* ]]; then
RC="--prerelease"
title="${title/rc/"RC"}"
else
# check if this version should not be marked latest
prevrelease=$(curl --retry 3 --silent -m 10 --connect-timeout 5 "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/latest")
prevvers=$(echo "$prevrelease" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' | sed -e "s/^v//")
vers=${VERSION#"v"}
echo "${prevvers},${vers}"
# sort -V -C returns 0 if args are ascending version order
if !(echo "${prevvers},${vers}" | tr ',' '\n' | sort -V -C)
then
LATEST="--latest=false"
fi
fi
gh release create $VERSION \
-t $title \
--notes-file $VERSION-release-notes.md \
--verify-tag \
$RC \
$LATEST \
release-artifacts/*
notification:
name: Email notification
runs-on: ubuntu-latest
needs: [check, release]
if: needs.check.outputs.buildonly == 'false'
steps:
- name: Format release email
id: format
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ needs.check.outputs.version }}
run: |
if grep -Eq '.+-rc' <<<"$VERSION"
then
RC_PREFIX="candidate "
fi
echo "mail_subj=Podman ${RC_PREFIX}${VERSION} Released" >> $GITHUB_OUTPUT
cat <<EOF>email_body.txt
Hi all,
Podman ${RC_PREFIX}${VERSION} is now available. You may view the full details at
https://github.com/${GITHUB_REPOSITORY}/releases/tag/$VERSION
Release ${RC_PREFIX}Notes:
--------------
EOF
echo "${GITHUB_TOKEN}" | gh auth login --with-token
gh release view "$VERSION" \
--repo "${GITHUB_REPOSITORY}" --json=body --jq '.body' >> email_body.txt
# If job fails, permit operator to observe contents in case helpful.
- name: Provide release e-mail contents for examination
run: cat email_body.txt
- name: Send release notification e-mail
# Ref: https://github.com/dawidd6/action-send-mail
uses: dawidd6/action-send-mail@v3.12.0
with:
server_address: ${{secrets.ACTION_MAIL_SERVER}}
server_port: 465
username: ${{secrets.ACTION_MAIL_USERNAME}}
password: ${{secrets.ACTION_MAIL_PASSWORD}}
subject: ${{ steps.format.outputs.mail_subj }}
to: Podman List <podman@lists.podman.io>
from: ${{secrets.ACTION_MAIL_SENDER}}
body: file://./email_body.txt
updatepodmanio:
name: Update podman.io
uses: ./.github/workflows/update-podmanio.yml
needs: [check, release]
if: needs.check.outputs.buildonly == 'false'
secrets: inherit
with:
version: ${{ needs.check.outputs.version }}