Skip to content

Commit

Permalink
Development: Add Helios-based deployment workflow for test servers an…
Browse files Browse the repository at this point in the history
…d reusable build logic (#10109)
  • Loading branch information
egekocabas authored Jan 29, 2025
1 parent c8c93d2 commit 72ca6ae
Show file tree
Hide file tree
Showing 3 changed files with 445 additions and 105 deletions.
192 changes: 87 additions & 105 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,118 +31,100 @@ on:
types:
- created

# Keep in sync with codeql-analysis.yml and test.yml and analysis-of-endpoint-connections.yml
env:
CI: true
node: 22
java: 21
RAW_URL: https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}
# Keep this filename in sync with the filename environment variable (PR_AUTO_BUILD_FILE_NAME) in the testserver-deployment.yml workflow

jobs:

build:
name: Build .war artifact
define-inputs:
name: Define Inputs
runs-on: ubuntu-latest
outputs:
release_upload: ${{ steps.set-upload-release.outputs.release_upload }}
release_url: ${{ steps.set-upload-release.outputs.release_url }}
release_path: ${{ steps.set-upload-release.outputs.release_path }}
release_name: ${{ steps.set-upload-release.outputs.release_name }}
release_type: ${{ steps.set-upload-release.outputs.release_type }}
docker_build: ${{ steps.set-docker-build.outputs.docker_build }}
docker_ref: ${{ steps.set-docker-ref.outputs.docker_ref }}
docker_build_tag: ${{ steps.set-docker-tag.outputs.docker_build_tag }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '${{ env.node }}'
cache: 'npm'
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '${{ env.java }}'
cache: 'gradle'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
- name: Production Build
run: ./gradlew -Pprod -Pwar clean bootWar
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: Artemis.war
path: build/libs/Artemis-*.war
- name: Upload Release Artifact
if: github.event_name == 'release' && github.event.action == 'created'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: build/libs/Artemis-${{ github.event.release.tag_name }}.war
asset_name: Artemis.war
asset_content_type: application/x-webarchive
- name: Set Upload Release Artifact Outputs
id: set-upload-release
run: |
# If event is release created, set the release_upload flag and the release artifact details
if [[ "${{ github.event_name }}" == "release" && "${{ github.event.action }}" == "created" ]]; then
echo "release_upload=true" >> $GITHUB_OUTPUT
echo "release_url=${{ github.event.release.upload_url }}" >> $GITHUB_OUTPUT
echo "release_path=build/libs/Artemis-${{ github.event.release.tag_name }}.war" >> $GITHUB_OUTPUT
echo "release_name=Artemis.war" >> $GITHUB_OUTPUT
echo "release_type=application/x-webarchive" >> $GITHUB_OUTPUT
else
echo "release_upload=false" >> $GITHUB_OUTPUT
fi
docker:
name: Build and Push Docker Image
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'ls1intum/Artemis' }}
runs-on: ubuntu-latest
steps:
- name: Compute Tag
uses: actions/github-script@v7
id: compute-tag
with:
result-encoding: string
script: |
if (context.eventName === "pull_request") {
return "pr-" + context.issue.number;
}
if (context.eventName === "release") {
return "latest";
}
if (context.eventName === "push") {
if (context.ref.startsWith("refs/tags/")) {
return context.ref.slice(10);
- name: Set Docker Build Flag
id: set-docker-build
run: |
if [[ ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'ls1intum/Artemis' }} ]]; then
echo "docker_build=true" >> $GITHUB_OUTPUT
else
echo "docker_build=false" >> $GITHUB_OUTPUT
fi
- name: Set Docker ref
if: ${{ steps.set-docker-build.outputs.docker_build == 'true' }}
id: set-docker-ref
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
# Checkout pull request HEAD commit instead of merge commit
# this is done to include the correct branch and git information inside the build
echo "docker_ref=${{ github.event.pull_request.head.ref }}" >> $GITHUB_OUTPUT
elif [[ "${{ github.event_name }}" == "push" ]]; then
echo "docker_ref=${{ github.ref_name }}" >> $GITHUB_OUTPUT
fi
- name: Compute Docker Tag
if: ${{ steps.set-docker-build.outputs.docker_build == 'true' }}
uses: actions/github-script@v7
id: compute-tag
with:
result-encoding: string
script: |
if (context.eventName === "pull_request") {
return "pr-" + context.issue.number;
}
if (context.eventName === "release") {
return "latest";
}
if (context.ref === "refs/heads/develop") {
return "develop";
if (context.eventName === "push") {
if (context.ref.startsWith("refs/tags/")) {
return context.ref.slice(10);
}
if (context.ref === "refs/heads/develop") {
return "develop";
}
}
}
return "FALSE";
- name: Git Checkout for PRs
if: ${{ github.event_name == 'pull_request' }}
# Checkout pull request HEAD commit instead of merge commit
# this is done to include the correct branch and git information inside the build
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Git Checkout for push actions
if: ${{ github.event_name == 'push' }}
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
- name: Git Checkout for push actions
if: ${{ github.event_name == 'release' }}
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Build and Push to GitHub Container Registry
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
if: ${{ steps.compute-tag.outputs.result != 'FALSE' }}
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push to GitHub Container Registry
uses: docker/build-push-action@v5
if: ${{ steps.compute-tag.outputs.result != 'FALSE' }}
with:
# beware that the linux/arm64 build from the registry is using an amd64 compiled .war file as
# the GitHub runners don't support arm64 and QEMU takes too long for emulating the build
platforms: linux/amd64,linux/arm64
file: ./docker/artemis/Dockerfile
context: .
tags: ghcr.io/ls1intum/artemis:${{ steps.compute-tag.outputs.result }}
push: true
cache-from: type=gha
cache-to: type=gha,mode=min
return "FALSE";
- name: Set Docker Tag
id: set-docker-tag
run: |
if [[ ${{ steps.compute-tag.outputs.result != 'FALSE' }} ]]; then
echo "docker_build_tag=${{ steps.compute-tag.outputs.result }}" >> $GITHUB_OUTPUT
fi
# TODO: Push to Docker Hub (develop + tag)
# TODO: Push to Chair Harbour (??)
call-build-workflow:
name: Call Build Workflow
needs: define-inputs
uses: ./.github/workflows/reusable-build.yml
with:
build_war: true
release_upload: ${{ needs.define-inputs.outputs.release_upload == 'true' }}
release_url: ${{ needs.define-inputs.outputs.release_url }}
release_path: ${{ needs.define-inputs.outputs.release_path }}
release_name: ${{ needs.define-inputs.outputs.release_name }}
release_type: ${{ needs.define-inputs.outputs.release_type }}
docker: ${{ needs.define-inputs.outputs.docker_build == 'true' }}
docker_ref: ${{ needs.define-inputs.outputs.docker_ref }}
docker_build_tag: ${{ needs.define-inputs.outputs.docker_build_tag }}
193 changes: 193 additions & 0 deletions .github/workflows/reusable-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
name: Build

on:
workflow_call:
inputs:
# Build job inputs
build_war:
description: "Whether to build and upload the .war artifact."
required: false
default: false
type: boolean
build_ref:
description: "Branch name, tag, or commit SHA to use for the build job. If not provided, it falls back to the default behavior of actions/checkout."
required: false
default: ''
type: string

# Upload Release Artifact job inputs
release_upload:
description: "Whether to upload the release artifact."
required: false
default: false
type: boolean
release_url:
description: "URL to upload the release artifact to."
required: false
default: ''
type: string
release_path:
description: "Path to the release artifact."
required: false
default: ''
type: string
release_name:
description: "Name of the release artifact."
required: false
default: ''
type: string
release_type:
description: "Content type of the release artifact."
required: false
default: ''
type: string

# Docker job inputs
docker:
description: "Whether to build and push a Docker image."
required: false
default: false
type: boolean
docker_ref:
description: "Branch name, tag, or commit SHA to use for the Docker job. If not provided, it falls back to the default behavior of actions/checkout."
required: false
default: ''
type: string
docker_build_tag:
description: "Tag to use when building Docker image."
required: false
default: ''
type: string

# Keep in sync with codeql-analysis.yml and test.yml and analysis-of-endpoint-connections.yml
env:
CI: true
node: 22
java: 21

jobs:
validate-inputs:
name: Validate Inputs
runs-on: ubuntu-latest
steps:
- name: Validate Inputs
run: |
# Check release related inputs
if [[ "${{ github.event.inputs.release_upload }}" ]]; then
# List of required release inputs
missing_inputs=()
# Check each required input
[[ -z "${{ inputs.release_url }}" || "${{ inputs.release_url }}" == '' ]] && missing_inputs+=("release_url")
[[ -z "${{ inputs.release_path }}" || "${{ inputs.release_path }}" == '' ]] && missing_inputs+=("release_path")
[[ -z "${{ inputs.release_name }}" || "${{ inputs.release_name }}" == '' ]] && missing_inputs+=("release_name")
[[ -z "${{ inputs.release_type }}" || "${{ inputs.release_type }}" == '' ]] && missing_inputs+=("release_type")
if [[ "${#missing_inputs[@]}" -gt 0 ]]; then
echo "::error::Release upload is set to true, but the following inputs are missing: ${missing_inputs[*]}"
exit 1
fi
fi
# Check Docker related inputs
if [[ "${{ github.event.inputs.docker }}" ]]; then
# Check whether all Docker inputs are set
if [[ "${{ github.event.inputs.docker_build_tag }}" == '' ]]; then
echo "::error::Docker build is set to true, but Docker build tag is not set."
exit 1
fi
fi
build:
name: Build .war artifact
if: ${{ inputs.build_war }}
needs: validate-inputs
runs-on: ubuntu-latest
steps:
# Git Checkout
- name: Git Checkout to the specific ref (if build_ref is set)
uses: actions/checkout@v4
if: ${{ inputs.build_ref != '' }}
with:
ref: ${{ inputs.build_ref }}
- name: Git Checkout (default)
uses: actions/checkout@v4
if: ${{ inputs.build_ref == '' }}
# Setup Node.js, Java and Gradle
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '${{ env.node }}'
cache: 'npm'
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '${{ env.java }}'
cache: 'gradle'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
# Build
- name: Production Build
run: ./gradlew -Pprod -Pwar clean bootWar
# Upload Artifact
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: Artemis.war
path: build/libs/Artemis-*.war
# Upload Artifact (Release)
- name: Upload Release Artifact
if: ${{ inputs.release_upload }}
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ inputs.release_url }}
asset_path: ${{ inputs.release_path }}
asset_name: ${{ inputs.release_name }}
asset_content_type: ${{ inputs.release_type }}

docker:
name: Build and Push Docker Image
if: ${{ inputs.docker }}
needs: validate-inputs
runs-on: ubuntu-latest
steps:
# Git Checkout
- name: Git Checkout to the specific ref (if docker_ref is set)
uses: actions/checkout@v4
if: ${{ inputs.docker_ref != '' }}
with:
ref: ${{ inputs.docker_ref }}
- name: Git Checkout (default)
uses: actions/checkout@v4
if: ${{ inputs.docker_ref == '' }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Build and Push to GitHub Container Registry
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push to GitHub Container Registry
uses: docker/build-push-action@v5
with:
# beware that the linux/arm64 build from the registry is using an amd64 compiled .war file as
# the GitHub runners don't support arm64 and QEMU takes too long for emulating the build
platforms: linux/amd64,linux/arm64
file: ./docker/artemis/Dockerfile
context: .
tags: ghcr.io/ls1intum/artemis:${{ inputs.docker_build_tag }}
push: true
cache-from: type=gha
cache-to: type=gha,mode=min

# TODO: Push to Docker Hub (develop + tag)

# TODO: Push to Chair Harbour (??)
Loading

0 comments on commit 72ca6ae

Please sign in to comment.