Skip to content

Release

Release #1510

Workflow file for this run

# This is the workflow for building release artifacts.
# Optionally, creating a release with those artifacts is possible by pushing a tag.
---
name: Release
on:
# Allow running this workflow manually from the Actions tab
workflow_dispatch:
push:
branches:
- main
tags:
- '*'
jobs:
Generate-Completion-Files:
name: Generate shell completion files
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Install protoc
run: sudo apt install -y protobuf-compiler
- name: Install Rust toolchain
run: |
rustup toolchain install stable --profile minimal
rustup default stable
- name: Generate shell completion files
run: cargo run --package xtask gencomp
- name: Upload shell completions
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: shell-completions
path: ./target/completions/
if-no-files-found: error
retention-days: 7
Build-CLI:
name: Build the CLI binary
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-20.04
- target: aarch64-unknown-linux-gnu
os: [self-hosted, linux, arm64]
- target: x86_64-apple-darwin
os: macos-14
- target: aarch64-apple-darwin
os: macos-14
- target: x86_64-pc-windows-msvc
os: windows-latest
extension: .exe
flags: --no-default-features
runs-on: ${{ matrix.os }}
steps:
- name: Checkout the repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: 0
- if: ${{ runner.os == 'macOS' }}
name: Install protoc
run: brew install protobuf
- if: ${{ runner.os == 'Linux' }}
name: Install protoc
run: sudo apt update && sudo apt install -y protobuf-compiler
- if: ${{ runner.os == 'Windows' }}
name: Install Rust toolchain
run: rustup toolchain install stable --profile minimal --target ${{ matrix.target }}
- if: ${{ runner.os != 'Windows' }}
name: Install Rust toolchain
run: |
curl https://sh.rustup.rs -sSf \
| sh -s -- -y --default-toolchain stable --profile minimal --target ${{ matrix.target }}
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Build Distributions
run: cargo build --release --target ${{ matrix.target }} ${{ matrix.flags }}
- name: Upload release artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: phylum-${{ matrix.target }}
path: ./target/${{ matrix.target }}/release/phylum${{ matrix.extension }}
if-no-files-found: error
retention-days: 7
Build-Release-Artifacts:
name: Build the release artifacts
needs: [Generate-Completion-Files, Build-CLI]
runs-on: ubuntu-latest
steps:
- name: Install host dependencies
run: sudo apt install -yq zip
- name: Checkout the repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
path: cli
- name: Download release artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
- name: Prep archives
run: |
for archive in phylum-*-apple-*/ phylum-*-linux-*/;
do
archive=$(echo "${archive}" | sed -e "s/\/$//")
cp -R shell-completions "${archive}/completions"
mkdir "${archive}/extensions"
for extension in npm poetry yarn pip bundle cargo
do
cp -R "cli/extensions/${extension}" "${archive}/extensions/${extension}"
done
cp cli/cli/src/install.sh "${archive}/install.sh"
chmod a+x "${archive}/phylum"
zip -r "${archive}.zip" "${archive}"
done
for archive in phylum-*-windows-*/;
do
archive=$(echo "${archive}" | sed -e "s/\/$//")
mv "${archive}/phylum.exe" "${archive}.exe"
done
- name: Upload release artifacts
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: release-archives
path: |
phylum-*.zip
phylum-*.exe
if-no-files-found: error
retention-days: 7
- name: Create release notes
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const fs = require("node:fs");
const tag = process.env.GITHUB_REF_NAME;
const prerelease = !tag.match(/^v(\d+\.)*\d+$/);
const ver = prerelease ? "Unreleased" : tag.replace("v", "");
const changelog = fs
.readFileSync("cli/CHANGELOG.md", { encoding: "utf-8" })
.split("\n");
const header = changelog.findIndex((line) => line.startsWith(`## ${ver}`));
const nextHeader = changelog.findIndex((line, idx) => idx > header && line.startsWith("## "));
if (header == -1 || nextHeader == -1) throw "Could not find headers";
const releaseNotes = changelog.slice(header + 1, nextHeader).join("\n").trim();
fs.writeFileSync("RELEASE-NOTES.txt", releaseNotes);
- name: Upload release notes
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: RELEASE-NOTES.txt
path: RELEASE-NOTES.txt
if-no-files-found: error
retention-days: 7
Release:
name: Create release from tag
needs: Build-Release-Artifacts
# Only run this job when pushing a tag
if: startsWith(github.ref, 'refs/tags/')
environment:
name: release
url: ${{ fromJSON(steps.create_release.outputs.result).data.html_url }}
runs-on: ubuntu-latest
steps:
- name: Download release artifacts
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: release-archives
- name: Sign archives
env:
OPENSSL_KEY: ${{ secrets.OPENSSL_KEY }}
run: |
for archive in phylum-*.zip;
do
openssl dgst -sha256 -sign <(printf "%s" "$OPENSSL_KEY") -out "${archive}.signature" "${archive}"
done
- name: Download release notes
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: RELEASE-NOTES.txt
- name: Create GitHub release
id: create_release
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
# The response is explicitly returned here so it will be available for other steps
script: |
const fs = require("node:fs");
const body = fs.readFileSync("RELEASE-NOTES.txt", { encoding: "utf-8" });
const response = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: process.env.GITHUB_REF_NAME,
prerelease: ${{ contains(github.ref, 'rc') }},
name: process.env.GITHUB_REF_NAME,
body: body,
});
console.log(response);
return response;
- name: Upload release assets
env:
UPLOAD_URL: ${{ fromJSON(steps.create_release.outputs.result).data.upload_url }}
# NOTE: The `UPLOAD_URL` is provided as an RFC 6570 URI templates, which is not usable directly
# without first trimming off the form-style query expansion part (e.g., {?var})
# Reference: https://docs.github.com/en/rest/releases/assets?apiVersion=2022-11-28#upload-a-release-asset
run: |
API_URL=$(printf "%s" "$UPLOAD_URL" | cut -d '{' -f 1)
for asset in phylum-*.zip* phylum-*.exe;
do
curl \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Content-Type: application/octet-stream" \
--data-binary "@$asset" \
"$API_URL?name=$asset"
done
- name: Trigger phylum-ci Docker image creation
# Don't trigger for pre-releases
if: ${{ !contains(github.ref, 'rc') }}
# Reference: https://docs.github.com/en/rest/repos/repos#create-a-repository-dispatch-event
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ secrets.GH_RELEASE_PAT }}
script: |
const response = await github.rest.repos.createDispatchEvent({
owner: "phylum-dev",
repo: "phylum-ci",
event_type: "build-push-docker-images",
client_payload: {CLI_version: process.env.GITHUB_REF_NAME},
});
console.log(response);
- name: Trigger documentation update
# Don't trigger for pre-releases
if: ${{ !contains(github.ref, 'rc') }}
# Reference: https://docs.github.com/en/rest/repos/repos#create-a-repository-dispatch-event
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ secrets.GH_RELEASE_PAT }}
script: |
const response = await github.rest.repos.createDispatchEvent({
owner: "phylum-dev",
repo: "documentation",
event_type: "trigger-update-submodule",
client_payload: {
repo_name: context.repo.repo,
tag_name: process.env.GITHUB_REF_NAME
},
});
console.log(response);