Add integration code for restricted algorithm implementations (#50) #77
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build images and test algorithms | |
on: | |
pull_request: | |
branches: main | |
push: | |
branches: main | |
defaults: | |
run: | |
shell: 'bash -Eeuo pipefail -l {0}' | |
jobs: | |
init: | |
name: Generate Jobs | |
runs-on: ubuntu-latest | |
outputs: | |
base_matrix: ${{ steps.generate-jobs.outputs.base_matrix }} | |
intermediate_matrix: ${{ steps.generate-jobs.outputs.intermediate_matrix }} | |
algo_matrix: ${{ steps.generate-jobs.outputs.algo_matrix }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 3 | |
- id: generate-jobs | |
name: Generate Jobs for modified base images or algorithms | |
run: | | |
base_matrix="$(./.ci/generate-build-matrix.sh 0-base-images)" | |
echo "base_matrix=$base_matrix" >> "$GITHUB_OUTPUT" | |
jq . <<<"$base_matrix" # print generated json for debugging | |
intermediate_matrix="$(./.ci/generate-build-matrix.sh 1-intermediate-images)" | |
echo "intermediate_matrix=$intermediate_matrix" >> "$GITHUB_OUTPUT" | |
jq . <<<"$intermediate_matrix" # print generated json for debugging | |
algo_matrix="$(./.ci/generate-build-matrix.sh)" | |
echo "algo_matrix=$algo_matrix" >> "$GITHUB_OUTPUT" | |
jq . <<<"$algo_matrix" # print generated json for debugging | |
build-base-images: | |
name: Build base images | |
runs-on: ubuntu-latest | |
needs: init | |
permissions: | |
contents: read | |
packages: write | |
if: fromJson(needs.init.outputs.base_matrix).algorithm_name[0] != null | |
strategy: | |
max-parallel: 3 | |
matrix: ${{ fromJson(needs.init.outputs.base_matrix) }} | |
fail-fast: false | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Compute (and check) version | |
id: version | |
run: | | |
version="$(./.ci/get-image-version.sh 0-base-images/${{ matrix.algorithm_name }})" | |
echo "version=$version" >> "$GITHUB_OUTPUT" | |
echo "$version" | |
- name: Compute Docker metadata | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ghcr.io/timeeval/${{ matrix.algorithm_name }} | |
tags: | | |
type=raw,value=latest | |
type=raw,value=${{ steps.version.outputs.version }} | |
labels: | | |
org.opencontainers.image.licenses=MIT | |
org.opencontainers.image.title=TimeEval ${{ matrix.algorithm_name }} base image | |
org.opencontainers.image.version=${{ steps.version.outputs.version }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login to registry | |
if: github.event_name != 'pull_request' | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build algorithm image | |
uses: docker/build-push-action@v5 | |
with: | |
context: "./0-base-images/${{ matrix.algorithm_name }}" | |
tags: ${{ steps.meta.outputs.tags }} | |
labels: ${{ steps.meta.outputs.labels }} | |
pull: true | |
push: ${{ github.event_name != 'pull_request' }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
build-intermediate-images: | |
name: Build intermediate images | |
runs-on: ubuntu-latest | |
needs: init | |
permissions: | |
contents: read | |
packages: write | |
if: fromJson(needs.init.outputs.intermediate_matrix).algorithm_name[0] != null | |
strategy: | |
max-parallel: 3 | |
matrix: ${{ fromJson(needs.init.outputs.intermediate_matrix) }} | |
fail-fast: false | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Compute (and check) version | |
id: version | |
run: | | |
version="$(./.ci/get-image-version.sh 1-intermediate-images/${{ matrix.algorithm_name }})" | |
echo "version=$version" >> "$GITHUB_OUTPUT" | |
echo "$version" | |
- name: Compute Docker metadata | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ghcr.io/timeeval/${{ matrix.algorithm_name }} | |
tags: | | |
type=raw,value=latest | |
type=raw,value=${{ steps.version.outputs.version }} | |
labels: | | |
org.opencontainers.image.licenses=MIT | |
org.opencontainers.image.title=TimeEval ${{ matrix.algorithm_name }} intermediate image | |
org.opencontainers.image.version=${{ steps.version.outputs.version }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Login to registry | |
if: github.event_name != 'pull_request' | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build algorithm image | |
uses: docker/build-push-action@v5 | |
with: | |
context: "./1-intermediate-images/${{ matrix.algorithm_name }}" | |
tags: ${{ steps.meta.outputs.tags }} | |
labels: ${{ steps.meta.outputs.labels }} | |
pull: true | |
push: ${{ github.event_name != 'pull_request' }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
test-algorithms: | |
name: Build and test algorithm images | |
runs-on: ubuntu-latest | |
needs: | |
- init | |
permissions: | |
contents: read | |
packages: write | |
if: fromJson(needs.init.outputs.algo_matrix).algorithm_name[0] != null | |
strategy: | |
max-parallel: 3 | |
matrix: ${{ fromJson(needs.init.outputs.algo_matrix) }} | |
fail-fast: false | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Set up Python 3.10 | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.10" | |
- name: Validate manifest | |
run: python validate_manifest.py --path ${{ matrix.algorithm_name }}/manifest.json | |
- name: Determine correct test dataset | |
id: dataset | |
run: | | |
dataset_name="$(python .ci/get_dataset_name.py ${{ matrix.algorithm_name }})" | |
echo "dataset_name=$dataset_name" >> "$GITHUB_OUTPUT" | |
echo "$dataset_name" | |
- name: Compute (and check) version | |
id: version | |
run: | | |
version="$(./.ci/get-image-version.sh ${{ matrix.algorithm_name }})" | |
echo "version=$version" >> "$GITHUB_OUTPUT" | |
echo "$version" | |
- name: Compute Docker metadata | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ghcr.io/timeeval/${{ matrix.algorithm_name }} | |
tags: | | |
type=raw,value=latest | |
type=raw,value=${{ steps.version.outputs.version }} | |
labels: | | |
org.opencontainers.image.title=TimeEval algorithm ${{ matrix.algorithm_name }} | |
org.opencontainers.image.version=${{ steps.version.outputs.version }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build algorithm image | |
uses: docker/build-push-action@v5 | |
with: | |
context: "./${{ matrix.algorithm_name }}" | |
tags: ${{ steps.meta.outputs.tags }} | |
# filter out license label, because it is set in the Dockerfile | |
labels: | | |
org.opencontainers.image.title=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.title'] }} | |
org.opencontainers.image.description=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.description'] }} | |
org.opencontainers.image.url=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.url'] }} | |
org.opencontainers.image.source=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.source'] }} | |
org.opencontainers.image.version=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }} | |
org.opencontainers.image.created=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }} | |
org.opencontainers.image.revision=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }} | |
pull: true | |
load: true | |
push: false | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
- name: Check if manifest is in the container | |
run: docker run --rm -e LOCAL_UID=1000 -e LOCAL_GID=1000 "ghcr.io/timeeval/${{ matrix.algorithm_name }}:latest" manifest | |
- name: Fix permissions of result folder | |
run: | | |
mkdir -p results | |
chmod 777 results | |
- name: Test training call | |
run: | | |
docker run --rm -e LOCAL_UID=1000 -e LOCAL_GID=1000 -v "${{ steps.dataset.outputs.dataset_name}}:/data/dataset.csv:ro" -v "$(pwd)/results:/results:rw" "ghcr.io/timeeval/${{ matrix.algorithm_name }}:latest" execute-algorithm '{"dataInput": "/data/dataset.csv", "dataOutput": "/results/scores.csv", "modelInput": "/results/model.pkl", "modelOutput": "/results/model.pkl", "executionType": "train", "customParameters": {"epochs": 1}}' | |
- name: Test execution call | |
run: | | |
docker run --rm -e LOCAL_UID=1000 -e LOCAL_GID=1000 -v "${{ steps.dataset.outputs.dataset_name}}:/data/dataset.csv:ro" -v "$(pwd)/results:/results:rw" "ghcr.io/timeeval/${{ matrix.algorithm_name }}:latest" execute-algorithm '{"dataInput": "/data/dataset.csv", "dataOutput": "/results/scores.csv", "modelInput": "/results/model.pkl", "modelOutput": "/results/model.pkl", "executionType": "execute", "customParameters": {"epochs": 1}}' | |
- name: Validate output | |
run: | | |
ls -alh results/* | |
python .ci/check_output.py "${{ matrix.algorithm_name }}" | |
# deployment for non-PRs and if all checks are successfull: | |
- name: Login to registry | |
if: github.event_name != 'pull_request' | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.repository_owner }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Build and push algorithm image | |
if: github.event_name != 'pull_request' | |
uses: docker/build-push-action@v5 | |
with: | |
context: "./${{ matrix.algorithm_name }}" | |
tags: ${{ steps.meta.outputs.tags }} | |
labels: ${{ steps.meta.outputs.labels }} | |
load: false | |
push: true | |
cache-from: type=gha | |
cache-to: type=gha,mode=max |