Skip to content

Release

Release #5

Workflow file for this run

name: Release
on:
push:
tags:
- 'v*'
workflow_dispatch:
inputs:
tag:
description: 'Tag to build (e.g., v0.2.2)'
required: true
jobs:
build:
strategy:
matrix:
include:
- os: ubuntu-22.04
arch: x86_64
- os: ubuntu-24.04-arm
arch: aarch64
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
cmake \
pkg-config \
rpm
- name: Get version
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ github.event.inputs.tag }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
# Strip 'v' prefix for version number
VERSION_NUM="${VERSION#v}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version_num=${VERSION_NUM}" >> $GITHUB_OUTPUT
- name: Build coz
run: |
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
make -j$(nproc)
- name: Create release package
run: |
VERSION="${{ steps.version.outputs.version_num }}"
ARCH="${{ matrix.arch }}"
PACKAGE_NAME="coz-${VERSION}-linux-${ARCH}"
mkdir -p "${PACKAGE_NAME}/bin"
mkdir -p "${PACKAGE_NAME}/lib"
mkdir -p "${PACKAGE_NAME}/include"
mkdir -p "${PACKAGE_NAME}/share/coz"
# Copy binaries
cp coz "${PACKAGE_NAME}/bin/"
cp build/libcoz/libcoz.so "${PACKAGE_NAME}/lib/"
# Copy headers
cp include/coz.h "${PACKAGE_NAME}/include/"
# Copy viewer (excluding development files)
cp -r viewer "${PACKAGE_NAME}/share/coz/"
rm -rf "${PACKAGE_NAME}/share/coz/viewer/node_modules"
rm -rf "${PACKAGE_NAME}/share/coz/viewer/ts"
rm -f "${PACKAGE_NAME}/share/coz/viewer/tsconfig.json"
rm -f "${PACKAGE_NAME}/share/coz/viewer/package*.json"
rm -f "${PACKAGE_NAME}/share/coz/viewer/Makefile"
rm -f "${PACKAGE_NAME}/share/coz/viewer/js/*.map"
# Copy documentation
cp README.md "${PACKAGE_NAME}/"
cp LICENSE.md "${PACKAGE_NAME}/"
# Create install script
cat > "${PACKAGE_NAME}/install.sh" << 'INSTALLEOF'
#!/bin/bash
set -e
PREFIX="${1:-/usr/local}"
echo "Installing coz to ${PREFIX}..."
install -d "${PREFIX}/bin"
install -d "${PREFIX}/lib"
install -d "${PREFIX}/include"
install -d "${PREFIX}/share/coz"
install -m 755 bin/coz "${PREFIX}/bin/"
install -m 755 lib/libcoz.so "${PREFIX}/lib/"
install -m 644 include/coz.h "${PREFIX}/include/"
cp -r share/coz/viewer "${PREFIX}/share/coz/"
echo "Installation complete!"
echo "To use coz, ensure ${PREFIX}/lib is in your library path:"
echo " export LD_LIBRARY_PATH=${PREFIX}/lib:$LD_LIBRARY_PATH"
echo "Run 'coz run --- ./your-program' to profile."
INSTALLEOF
sed -i 's/^ //' "${PACKAGE_NAME}/install.sh"
chmod +x "${PACKAGE_NAME}/install.sh"
# Create tarball
tar -czvf "${PACKAGE_NAME}.tar.gz" "${PACKAGE_NAME}"
echo "PACKAGE_NAME=${PACKAGE_NAME}" >> $GITHUB_ENV
- name: Create .deb package
run: |
VERSION="${{ steps.version.outputs.version_num }}"
ARCH="${{ matrix.arch }}"
# Map architecture to Debian naming
if [ "${ARCH}" = "x86_64" ]; then
DEB_ARCH="amd64"
elif [ "${ARCH}" = "aarch64" ]; then
DEB_ARCH="arm64"
else
DEB_ARCH="${ARCH}"
fi
DEB_NAME="coz_${VERSION}_${DEB_ARCH}"
# Create Debian package structure
mkdir -p "${DEB_NAME}/DEBIAN"
mkdir -p "${DEB_NAME}/usr/bin"
mkdir -p "${DEB_NAME}/usr/lib"
mkdir -p "${DEB_NAME}/usr/include"
mkdir -p "${DEB_NAME}/usr/share/coz"
mkdir -p "${DEB_NAME}/usr/share/doc/coz"
# Copy files
cp coz "${DEB_NAME}/usr/bin/"
cp build/libcoz/libcoz.so "${DEB_NAME}/usr/lib/"
cp include/coz.h "${DEB_NAME}/usr/include/"
# Copy viewer
cp -r viewer "${DEB_NAME}/usr/share/coz/"
rm -rf "${DEB_NAME}/usr/share/coz/viewer/node_modules"
rm -rf "${DEB_NAME}/usr/share/coz/viewer/ts"
rm -f "${DEB_NAME}/usr/share/coz/viewer/tsconfig.json"
rm -f "${DEB_NAME}/usr/share/coz/viewer/package*.json"
rm -f "${DEB_NAME}/usr/share/coz/viewer/Makefile"
rm -f "${DEB_NAME}/usr/share/coz/viewer/js/*.map"
# Copy documentation
cp README.md "${DEB_NAME}/usr/share/doc/coz/"
cp LICENSE.md "${DEB_NAME}/usr/share/doc/coz/copyright"
# Calculate installed size (in KB)
INSTALLED_SIZE=$(du -sk "${DEB_NAME}" | cut -f1)
# Create control file
cat > "${DEB_NAME}/DEBIAN/control" << EOF
Package: coz
Version: ${VERSION}
Section: devel
Priority: optional
Architecture: ${DEB_ARCH}
Installed-Size: ${INSTALLED_SIZE}
Maintainer: Emery Berger <emery@cs.umass.edu>
Homepage: https://github.com/plasma-umass/coz
Description: Coz: Causal Profiler
Coz is a causal profiler that measures optimization potential.
Unlike traditional profilers that show where time is spent,
Coz predicts whether optimizing a piece of code will actually
improve overall program performance.
EOF
# Remove leading spaces from heredoc
sed -i 's/^ //' "${DEB_NAME}/DEBIAN/control"
# Create postinst script to run ldconfig
cat > "${DEB_NAME}/DEBIAN/postinst" << 'EOF'
#!/bin/sh
set -e
ldconfig
EOF
sed -i 's/^ //' "${DEB_NAME}/DEBIAN/postinst"
chmod 755 "${DEB_NAME}/DEBIAN/postinst"
# Create postrm script
cat > "${DEB_NAME}/DEBIAN/postrm" << 'EOF'
#!/bin/sh
set -e
ldconfig
EOF
sed -i 's/^ //' "${DEB_NAME}/DEBIAN/postrm"
chmod 755 "${DEB_NAME}/DEBIAN/postrm"
# Set proper permissions
chmod 755 "${DEB_NAME}/usr/bin/coz"
chmod 755 "${DEB_NAME}/usr/lib/libcoz.so"
# Build the .deb package
dpkg-deb --build --root-owner-group "${DEB_NAME}"
echo "DEB_NAME=${DEB_NAME}" >> $GITHUB_ENV
- name: Create .rpm package
run: |
VERSION="${{ steps.version.outputs.version_num }}"
ARCH="${{ matrix.arch }}"
# Map architecture to RPM naming
if [ "${ARCH}" = "x86_64" ]; then
RPM_ARCH="x86_64"
elif [ "${ARCH}" = "aarch64" ]; then
RPM_ARCH="aarch64"
else
RPM_ARCH="${ARCH}"
fi
# Set up RPM build directory structure
mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
mkdir -p rpmbuild/BUILDROOT/coz-${VERSION}-1.${RPM_ARCH}
# Create the installed file structure
BUILDROOT="rpmbuild/BUILDROOT/coz-${VERSION}-1.${RPM_ARCH}"
mkdir -p "${BUILDROOT}/usr/bin"
mkdir -p "${BUILDROOT}/usr/lib64"
mkdir -p "${BUILDROOT}/usr/include"
mkdir -p "${BUILDROOT}/usr/share/coz"
mkdir -p "${BUILDROOT}/usr/share/doc/coz"
# Copy files
cp coz "${BUILDROOT}/usr/bin/"
cp build/libcoz/libcoz.so "${BUILDROOT}/usr/lib64/"
cp include/coz.h "${BUILDROOT}/usr/include/"
# Copy viewer
cp -r viewer "${BUILDROOT}/usr/share/coz/"
rm -rf "${BUILDROOT}/usr/share/coz/viewer/node_modules"
rm -rf "${BUILDROOT}/usr/share/coz/viewer/ts"
rm -f "${BUILDROOT}/usr/share/coz/viewer/tsconfig.json"
rm -f "${BUILDROOT}/usr/share/coz/viewer/package*.json"
rm -f "${BUILDROOT}/usr/share/coz/viewer/Makefile"
rm -f "${BUILDROOT}/usr/share/coz/viewer/js/*.map"
# Copy documentation
cp README.md "${BUILDROOT}/usr/share/doc/coz/"
cp LICENSE.md "${BUILDROOT}/usr/share/doc/coz/"
# Set permissions
chmod 755 "${BUILDROOT}/usr/bin/coz"
chmod 755 "${BUILDROOT}/usr/lib64/libcoz.so"
# Create spec file
cat > rpmbuild/SPECS/coz.spec << EOF
Name: coz
Version: ${VERSION}
Release: 1
Summary: Coz: Causal Profiler
License: BSD-2-Clause
URL: https://github.com/plasma-umass/coz
%description
Coz is a causal profiler that measures optimization potential.
Unlike traditional profilers that show where time is spent,
Coz predicts whether optimizing a piece of code will actually
improve overall program performance.
%install
cp -a %{_builddir}/../BUILDROOT/coz-${VERSION}-1.${RPM_ARCH}/* %{buildroot}/
%files
%license /usr/share/doc/coz/LICENSE.md
%doc /usr/share/doc/coz/README.md
/usr/bin/coz
/usr/lib64/libcoz.so
/usr/include/coz.h
/usr/share/coz
%post
/sbin/ldconfig
%postun
/sbin/ldconfig
EOF
sed -i 's/^ //' rpmbuild/SPECS/coz.spec
# Build the RPM
rpmbuild --define "_topdir $(pwd)/rpmbuild" \
--define "_builddir $(pwd)/rpmbuild/BUILD" \
--define "_rpmdir $(pwd)/rpmbuild/RPMS" \
--define "_buildrootdir $(pwd)/rpmbuild/BUILDROOT" \
--target "${RPM_ARCH}" \
-bb rpmbuild/SPECS/coz.spec
# Move RPM to current directory with consistent naming
RPM_NAME="coz-${VERSION}-1.${RPM_ARCH}.rpm"
mv rpmbuild/RPMS/${RPM_ARCH}/*.rpm "./${RPM_NAME}"
echo "RPM_NAME=${RPM_NAME}" >> $GITHUB_ENV
- name: Upload tarball artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.PACKAGE_NAME }}
path: ${{ env.PACKAGE_NAME }}.tar.gz
retention-days: 5
- name: Upload deb artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.DEB_NAME }}
path: ${{ env.DEB_NAME }}.deb
retention-days: 5
- name: Upload rpm artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.RPM_NAME }}
path: ${{ env.RPM_NAME }}
retention-days: 5
release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Get version
id: version
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
VERSION="${{ github.event.inputs.tag }}"
else
VERSION="${GITHUB_REF#refs/tags/}"
fi
VERSION_NUM="${VERSION#v}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version_num=${VERSION_NUM}" >> $GITHUB_OUTPUT
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: List artifacts
run: find artifacts -type f
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.version }}
name: Coz ${{ steps.version.outputs.version_num }}
draft: false
prerelease: ${{ contains(steps.version.outputs.version, '-') }}
generate_release_notes: true
files: |
artifacts/**/*.tar.gz
artifacts/**/*.deb
artifacts/**/*.rpm