Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

github Actions for Linux #46

Merged
merged 2 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .github/workflows/build_and_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: Build and Release Performous

# Controls when the workflow will run
on:
# Triggers the workflow on merges to master, release branches,
# all PRs, and release tags
push:
branches:
- master
- '[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+'
tags:
- '[0-9]+\.[0-9]+\.[0-9]+'
- '[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+'

# On anything pull request related
pull_request:

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Note: entire jobs or sections can be disabled by adding
# if: ${{ false }} to the definition column
jobs:
# Determine version
determine_version:
name: Determine the version to be used
runs-on: ubuntu-latest
outputs:
latest_tag_version: ${{ steps.versioning.outputs.latest_tag_version }}
latest_full_tag_version: ${{ steps.versioning.outputs.latest_full_tag_version }}
version_major: ${{ steps.versioning.outputs.version_major }}
version_minor: ${{ steps.versioning.outputs.version_minor }}
version_patch: ${{ steps.versioning.outputs.version_patch }}
version_tweak: ${{ steps.versioning.outputs.version_tweak }}
complete_version: ${{ steps.versioning.outputs.complete_version }}
steps:
- name: Determine the complete version
id: versioning
run: |
# Always check the tags on master since it will have the latest.
# Tags will trigger their own workflow and version names
git clone --recursive ${{ github.server_url }}/${{ github.repository }} performous_composer
cd performous_composer
LATEST_TAG_VERSION=$(git describe --tags --abbrev=0 || echo 1.0.0)
LATEST_FULL_TAG_VERSION=$(git describe --tags || echo 1.0.0)
echo "latest_tag_version=$(git describe --tags --abbrev=0 || echo 1.0.0)" >> $GITHUB_OUTPUT
echo "latest_full_tag_version=$(git describe --tags || echo 1.0.0)" >> $GITHUB_OUTPUT
echo "version_major=$(cut -d '.' -f 1 <<< $(git describe --tags --abbrev=0 || echo 1.0.0))" >> $GITHUB_OUTPUT
echo "version_minor=$(cut -d '.' -f 2 <<< $(git describe --tags --abbrev=0 || echo 1.0.0))" >> $GITHUB_OUTPUT
echo "version_patch=$(cut -d '.' -f 3 <<< $(git describe --tags --abbrev=0 || echo 1.0.0))" >> $GITHUB_OUTPUT
echo "version_tweak=0" >> $GITHUB_OUTPUT
echo "complete_version=$(if [ $GITHUB_REF_TYPE = 'tag' ]; then echo $GITHUB_REF_NAME; elif [ $GITHUB_REF_TYPE = 'branch' ] && [ $GITHUB_REF_NAME = 'master' ]; then echo $LATEST_FULL_TAG_VERSION-beta; elif [ $GITHUB_REF_TYPE = 'branch' ] && [ $GITHUB_REF_NAME != 'master' ]; then echo $LATEST_TAG_VERSION-${{github.event.pull_request.number}}-${GITHUB_SHA::7}-alpha; fi)" >> $GITHUB_OUTPUT

# Set up a release that packages will be published to.
create_release:
name: Create a release
runs-on: ubuntu-latest
# Make sure the output variable for this step is set so it
# can be consumed by later build steps
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
steps:
- name: Create the Main release
id: create_release
if: ${{ github.event_name != 'pull_request' && github.ref_type == 'tag' }}
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
release_name: Performous ${{ github.ref_name }}
draft: true
prerelease: false

# Pull in the Linux build workflow
Linux_Packages:
name: Build the Linux packages
uses: ./.github/workflows/linux.yml
with:
package_complete_version: ${{ needs.determine_version.outputs.complete_version }}
release_upload_url: ${{ needs.create_release.outputs.upload_url }}
needs:
- determine_version
- create_release

# Pull in the AppImage build workflow
#AppImage_Package:
# name: Build the AppImage package
# uses: ./.github/workflows/appimage.yml
# with:
# package_complete_version: ${{ needs.determine_version.outputs.complete_version }}
# release_upload_url: ${{ needs.create_release.outputs.upload_url }}
# needs:
# - determine_version
# - create_release

# Pull in the MacOS build workflow
#MacOS_Package:
# name: Build the MacOS package
# uses: ./.github/workflows/macos.yml
# with:
# package_complete_version: ${{ needs.determine_version.outputs.complete_version }}
# release_upload_url: ${{ needs.create_release.outputs.upload_url }}
# needs:
# - determine_version
# - create_release

# Pull in the Windows build workflow
#Windows_Packages:
# name: Build the Windows packages
# uses: ./.github/workflows/windows.yml
# with:
# package_complete_version: ${{ needs.determine_version.outputs.complete_version }}
# release_upload_url: ${{ needs.create_release.outputs.upload_url }}
# needs:
# - determine_version
# - create_release
65 changes: 65 additions & 0 deletions .github/workflows/comment_on_pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Comment on pull request

on:
# Only run when the other workflow is completed since
# the build workflow only publishes artifacts after it has completed
workflow_run:
workflows: [ 'Build and Release Performous' ]
types: [completed]

jobs:
pr_comment:
name: Add packages to PRs
if: github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Get the PR number
run: |
# Query the issue search API to get the PR associated with it
PR_RAW=$(curl 'https://api.github.com/search/issues?q=${{ github.event.workflow_run.head_commit.id }}')
# Get the event number from the search results, which will
# be the PR number
PR_NUM=$(echo $PR_RAW | jq '.items[].number')
echo "PR_NUM=${PR_NUM}" >> ${GITHUB_ENV}

- name: Comment on PR
uses: actions/github-script@v5
with:
# This snippet is public-domain, taken from
# https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml
# and modified to allow comments on external PRs
script: |
async function upsertComment(owner, repo, issue_number, purpose, body) {
const {data: comments} = await github.rest.issues.listComments(
{owner, repo, issue_number});
const marker = `<!-- bot: ${purpose} -->`;
body = marker + "\n" + body;
const existing = comments.filter((c) => c.body.includes(marker));
if (existing.length > 0) {
const last = existing[existing.length - 1];
core.info(`Updating comment ${last.id}`);
await github.rest.issues.updateComment({
owner, repo,
body,
comment_id: last.id,
});
} else {
core.info(`Creating a comment in issue / PR ${issue_number}`);
await github.rest.issues.createComment({issue_number, body, owner, repo});
}
}
const {owner, repo} = context.repo;
const run_id = '${{github.event.workflow_run.id}}';
const artifacts = await github.paginate(
github.rest.actions.listWorkflowRunArtifacts, {owner, repo, run_id});
if (!artifacts.length) {
return core.error(`No artifacts found`);
}
let body = `Download the artifacts for this pull request:\n`;
for (const art of artifacts) {
body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
}
body += ` \n\nThis service is provided by [nightly.link](https://github.com/oprypin/nightly.link). These artifacts will expire in 90 days and will not be available for download after that time.`;
core.info("Review thread message body:", body);
await upsertComment(owner, repo, ${{ env.PR_NUM }},
"nightly-link", body);
190 changes: 190 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
name: Build Linux Packages

on:
# Run on a schedule to get monthly updates
schedule:
- cron: "0 0 28 * *"

# Run when called from other workflows
workflow_call:
inputs:
package_complete_version:
description: 'The output of the complete_version of the "determine_version" job from the build_and_release.yml workflow'
required: true
type: string
release_upload_url:
description: 'The output of the "create_release" job from the build_and_release.yml workflow'
required: true
type: string

env:
REGISTRY: ghcr.io
REPO_NAME: ${{ github.repository_owner }}

jobs:
# Decide if we need to build the containers on this run
determine_docker_version:
name: Determine whether to build the containers or not
runs-on: ubuntu-latest
outputs:
build_docker_containers: ${{ steps.version.outputs.build_docker_containers }}
steps:
- name: Checkout
id: checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Determine version
id: version
run: |
# Only run the container builds when something in the docker folder or
# this workflow has changed from master, or if it was cron triggered
GIT_OUTPUT="$(git log -n 2 --stat)"
if [ $(echo ${GIT_OUTPUT} | grep -c docker/) -gt 0 ] || [ $(echo ${GIT_OUTPUT} | grep -c .github/workflows/linux.yml) -gt 0 ] || [ '${{ github.event_name }}' = 'schedule' ]; then
echo "build_docker_containers=true" >> $GITHUB_OUTPUT
else
echo "build_docker_containers=false" >> $GITHUB_OUTPUT
fi

build_packages:
name: Build the Linux packages
runs-on: ubuntu-latest
needs:
- determine_docker_version
strategy:
matrix:
include:
- os: ubuntu
version: 20.04
- os: ubuntu
version: 22.04
- os: debian
version: 10
- os: debian
version: 11
- os: fedora
version: 34
- os: fedora
version: 35
## FFMPEG5 causes issues
ooshlablu marked this conversation as resolved.
Show resolved Hide resolved
#- os: fedora
# version: 36
steps:
- name: Container name
run: |
# Figure out the container name we'll use for the build
BUILD_CONTAINER=${{ env.REGISTRY }}/${{ env.REPO_NAME }}/composer-deps:${{ matrix.os }}-${{ matrix.version }}
echo "CONTAINER_NAME=${BUILD_CONTAINER}" >> $GITHUB_ENV

- name: Checkout
uses: actions/checkout@v3

- name: Login to the container registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ env.REPO_NAME }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build ${{ matrix.os }} ${{ matrix.version }} Container
if: ${{ needs.determine_docker_version.outputs.build_docker_containers == 'true' }}
uses: docker/build-push-action@v3
with:
context: docker/
file: ./docker/Dockerfile.${{ matrix.os }}
load: true
tags: ${{ env.CONTAINER_NAME }}
build-args: OS_VERSION=${{ matrix.version }}

- name: Build package
# Don't build the packages if triggered by cron because it will not
# have the correct inputs required to construct the package names correctly.
# The cron schedule is really for making sure the docker containers are
# up-to-date anyway.
if: ${{ github.event_name != 'schedule' }}
run: |
# Set the correct version in cmake
PACKAGE_VERSION=${{ inputs.package_complete_version }}
EXTRA_CMAKE_ARGS="-DPERFORMOUS_VERSION=${PACKAGE_VERSION}"

# Decide if we should build a 'Release' package or a 'RelWithDebInfo' (default)
# For some reason, building with 'RelWithDebInfo' (default) doesn't work
# specifically on PRs, so we'll just build Releases for everything for now
#if [ '${{ github.event_name }}' != 'pull_request' ]; then
RELEASE_TYPE="-R"
#fi

# Only pull the container if it wasn't built locally
if [ '${{ needs.determine_docker_version.outputs.build_docker_containers }}' = 'false' ]; then
docker pull ${{ env.CONTAINER_NAME }}
fi

# Run the build inside the docker containers using the
# build script that was pulled inside during the build
docker run --rm -v $(pwd):/github_actions_build/ ${{ env.CONTAINER_NAME }} ./build_composer.sh -g -D /github_actions_build/ -E ${EXTRA_CMAKE_ARGS} ${RELEASE_TYPE}
# Do some mangling to make a unique name based on the OS
# This is needed so we don't overwite in the release each time.
# We should probably investigate what cmake can do for package output
# to make this cleaner in the future
WORK_DIR=$(pwd)
PACKAGE_PATH=$(ls ${WORK_DIR}/build/Composer*64.*)
PACKAGE_NAME=$(basename ${PACKAGE_PATH})
PACKAGE_SUFFIX=$(echo ${PACKAGE_NAME} | sed 's/^.*\(.\{4\}\)/\1/')
NEW_PACKAGE_NAME="${WORK_DIR}/Composer-${PACKAGE_VERSION}-${{ matrix.os }}_${{ matrix.version }}${PACKAGE_SUFFIX}"
MASTER_NEW_PACKAGE_NAME="${WORK_DIR}/Composer-latest-${{ matrix.os }}_${{ matrix.version }}${PACKAGE_SUFFIX}"
cp ${PACKAGE_PATH} ${MASTER_NEW_PACKAGE_NAME}
cp ${PACKAGE_PATH} ${NEW_PACKAGE_NAME}
ARTIFACT_NAME=$(basename ${NEW_PACKAGE_NAME})
MASTER_ARTIFACT_NAME=$(basename ${MASTER_NEW_PACKAGE_NAME})
echo "ARTIFACT_PATH=${NEW_PACKAGE_NAME}" >> ${GITHUB_ENV}
echo "ARTIFACT_NAME=${ARTIFACT_NAME}" >> ${GITHUB_ENV}
echo "MASTER_ARTIFACT_PATH=${MASTER_NEW_PACKAGE_NAME}" >> ${GITHUB_ENV}
echo "MASTER_ARTIFACT_NAME=${MASTER_ARTIFACT_NAME}" >> ${GITHUB_ENV}

#- name: Run unit tests
# if: ${{ github.event_name != 'schedule' }}
# run: |
# # Run the containers with the script for each testing suite
# docker run --rm -v $(pwd):/github_actions_build/ ${{ env.CONTAINER_NAME }} ./run_tests.sh

# Upload artifacts during pull-requests
- name: Upload artifact
uses: actions/upload-artifact@v3
if: ${{ github.event_name == 'pull_request' }}
with:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.ARTIFACT_PATH }}

# Upload artifacts on master
- name: Upload artifact with unified name
if: ${{ github.ref == 'refs/heads/master' }}
uses: actions/upload-artifact@v3
with:
name: ${{ env.MASTER_ARTIFACT_NAME }}
path: ${{ env.MASTER_ARTIFACT_PATH }}

# Upload artifacts to releases only during Release events
- name: Upload artifacts to tagged release
id: upload_assets
if: ${{ github.event_name != 'pull_request' && github.ref_type == 'tag' }}
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ inputs.release_upload_url }}
asset_path: ${{ env.ARTIFACT_PATH }}
asset_name: ${{ env.ARTIFACT_NAME }}
asset_content_type: application/octet-stream

- name: Push container
uses: docker/build-push-action@v3
# Containers can't be pushed during PRs because of the way permissions
# are delegated to secrets.GITHUB_TOKEN
if: ${{ needs.determine_docker_version.outputs.build_docker_containers == 'true' && github.event_name != 'pull_request' }}
with:
context: docker/
file: ./docker/Dockerfile.${{ matrix.os }}
push: true
tags: ${{ env.CONTAINER_NAME }}
build-args: OS_VERSION=${{ matrix.version }}
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,3 @@ set(CMAKE_AUTOMOC ON)

# Sources
add_subdirectory(src)

Loading