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

Improvements to Container CD #385

Closed
wants to merge 20 commits into from
Closed
80 changes: 80 additions & 0 deletions .github/workflows/composite/docker-build/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

# Source: https://github.com/intel/ai-containers/blob/main/.github/action.yml

---
name: Build Container Example
description: Given the inputs found below, build all containers found in a docker-compose.yaml file for a given configuration
author: tyler.titsworth@intel.com
inputs:
example_dir:
description: Directory with docker-compose.yaml to build
required: true
type: string
env_overrides:
description: Bash Env Variable Overrides in `KEY=VAL && KEY2=VAL2` format
required: false
type: string
registry:
description: Container Registry URL
required: false
default: 'opea-project'
type: string
outputs:
container-example:
description: "Container Example"
value: ${{ steps.container-output.outputs.example }}
runs:
using: composite
steps:
# This step generates a random number to use as the project number
# which can help avoid collisions with parallel builds on the same system
- name: Generate Project Number
shell: bash
run: echo "project-number=$(shuf -i 0-10000 -n1)" >> $GITHUB_ENV
- name: Build Containers
shell: bash
run: |
REGISTRY=${{ inputs.registry }} \
COMPOSE_PROJECT_NAME=${{ env.project-number }} \
${{ inputs.env_overrides }} docker compose -p ${{ env.project-number }} up --build --force-recreate --always-recreate-deps --no-start
working-directory: ${{ inputs.example_dir }}
- name: Print Containers
id: container-output
shell: bash
run: |
mkdir matrix
images=$(REGISTRY=${{ inputs.registry }} \
COMPOSE_PROJECT_NAME=${{ env.project-number }} \
${{ inputs.env_overrides }} docker compose -p ${{ env.project-number }} images --format json)
for image in $(echo $images | jq -r --arg registry "$REGISTRY" '.[] | select(.Repository | contains($registry)) | .Tag'); do
echo "$image" > matrix/$image.txt
done
echo "example=${{ inputs.example_dir }}" | tr '/' '_' >> $GITHUB_OUTPUT
working-directory: ${{ inputs.example_dir }}
- uses: actions/upload-artifact@v4
with:
name: ${{ env.project-number }}-${{ steps.container-output.outputs.example }}
path: ${{ inputs.example_dir }}/matrix/*
retention-days: 1
overwrite: true
- name: Push Containers
shell: bash
run: |
REGISTRY=${{ inputs.registry }} \
COMPOSE_PROJECT_NAME=${{ env.project-number }} \
${{ inputs.env_overrides }} docker compose -p ${{ env.project-number }} push
working-directory: ${{ inputs.example_dir }}
- name: Un-Tag Containers
if: ${{ always() }}
shell: bash
run: |
REGISTRY=${{ inputs.registry }} \
COMPOSE_PROJECT_NAME=${{ env.project-number }} \
${{ inputs.env_overrides }} docker compose -p ${{ env.project-number }} down --rmi all
working-directory: ${{ inputs.example_dir }}
- name: Remove Containers
if: ${{ always() }}
shell: bash
run: docker system prune --force
26 changes: 26 additions & 0 deletions .github/workflows/composite/scan/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

# Source: https://github.com/intel/ai-containers/blob/main/.github/scan/action.yml

name: 'Aqua Security Trivy'
description: 'Scans container images for vulnerabilities with Trivy without building the image. For use behind firewalls.'
author: 'tyler.titsworth@intel.com'
inputs:
image-ref:
description: 'image reference(for backward compatibility)'
required: true
output:
description: 'writes results to a file with the specified file name'
required: true
runs:
using: 'docker'
image: "docker://ghcr.io/aquasecurity/trivy"
entrypoint: trivy
args:
- '--timeout=30m'
- image
- '--format=table'
- '--no-progress'
- '--output=${{ inputs.output }}'
- ${{ inputs.image-ref }}
44 changes: 0 additions & 44 deletions .github/workflows/container-build.yml

This file was deleted.

197 changes: 197 additions & 0 deletions .github/workflows/container-ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

name: Example Container CI
permissions: read-all
on:
workflow_call:
inputs:
example_dir:
required: true
type: string
scan:
default: true
required: false
type: boolean
test:
default: true
required: false
type: boolean
publish:
default: false
required: false
type: boolean
jobs:
####################################################################################################
# Compose Build
####################################################################################################
build-containers:
runs-on: ubuntu-latest # local registry label
outputs:
example: ${{ steps.build-example.outputs.container-example }}
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
with:
registry: ${{ secrets.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Build Container example
id: build-example
uses: ./.github/workflows/composite/docker-build
with:
example_dir: ${{ inputs.example_dir }}
env_overrides: ${{ inputs.env_overrides || env.env_overrides || '' }}
registry: ${{ secrets.REGISTRY }}
####################################################################################################
# Trivy Scan
####################################################################################################
setup-scan:
needs: [build-containers]
if: ${{ fromJSON(inputs.scan) }}
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.scan-matrix.outputs.matrix }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
path: matrix
- name: Set Matrix
id: scan-matrix
run: echo "matrix=$(cat matrix/*-${{ needs.build-containers.outputs.example }}/*.txt | jq -R '.' | jq -sc '. | unique')" >> $GITHUB_OUTPUT
scan-containers:
needs: [setup-scan]
if: ${{ fromJSON(inputs.scan) }}
runs-on: ubuntu-latest # local registry label
strategy:
matrix:
container: ${{ fromJSON(needs.setup-scan.outputs.matrix) }}
fail-fast: false
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
with:
registry: ${{ secrets.REGISTRY }}
username: ${{ secrets.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Downcase example Dir
run: echo "example_dir=${EXAMPLE_DIR,,}" >> ${GITHUB_ENV}
env:
EXAMPLE_DIR: ${{ inputs.example_dir }}
- name: Pull Image
run: docker pull ${{ secrets.REGISTRY }}/${{ env.example_dir }}:${{ matrix.container }}
- name: Scan Container
uses: ./.github/workflows/composite/scan
with:
image-ref: ${{ secrets.REGISTRY }}/${{ env.example_dir }}:${{ matrix.container }}
output: ${{ matrix.container }}-${{ env.example_dir }}-scan.txt
- name: Cleanup
if: always()
run: docker rmi -f ${{ secrets.REGISTRY }}/${{ env.example_dir }}:${{ matrix.container }}
# Requires GitHub Advanced Security
# - uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11
# with:
# sarif_file: '${{ matrix.container }}-${{ env.example_dir }}-scan.sarif'
# category: '${{ matrix.container }}'
# continue-on-error: true
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
with:
name: ${{ matrix.container }}-${{ env.example_dir }}-scan
path: ${{ matrix.container }}-${{ env.example_dir }}-scan.txt
overwrite: true
####################################################################################################
# Validation
####################################################################################################
setup-test:
needs: [build-containers]
if: ${{ fromJSON(inputs.test) }}
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.test-matrix.outputs.matrix }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: 0
- name: Get Tests
id: test-matrix
run: |
echo "matrix=$(find ${{ inputs.example_dir }}/tests -type f -name 'test_*.sh' -print | \
sed -n 's|.*/\(test_[^_]*_on_\([^\.]*\)\).sh|\{"test": "\1", "hardware_label": "\2"}|p' | \
jq -sc .)" >> $GITHUB_OUTPUT
# ex: [{"test":"test_audioqna_on_xeon","hardware_label":"xeon"},{"test":"test_audioqna_on_gaudi","hardware_label":"gaudi"}]
test-containers:
needs: [setup-test]
if: ${{ needs.setup-test.outputs.matrix != '[]' && fromJSON(inputs.test) }}
runs-on: ${{ matrix.tests.hardware_label }}
strategy:
matrix:
tests: ${{ fromJson(needs.setup-test.outputs.matrix) }}
experimental: [true]
fail-fast: false
steps:
- uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit
- name: Set Variables
run: |
echo "lower_example=${EXAMPLE_DIR,,}" >> ${GITHUB_ENV}
echo "date=$(date +%Y%m%d%H%M%S)" >> ${GITHUB_ENV}
env:
EXAMPLE_DIR: ${{ inputs.example_dir }}
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: azure/setup-kubectl@v4
if: ${{ contains(matrix.tests.test, "gmc") || contains(matrix.tests.test, "manifest") }}
- name: Run Test
run: bash ${{ matrix.tests.test }}.sh
env:
REGISTRY: ${{ secrets.REGISTRY }}
IMAGE_REPO: $OPEA_IMAGE_REPO
IMAGE_TAG: $GITHUB_RUN_NUMBER
APP_NAMESPACE: $lower_example-$date
ROLLOUT_TIMEOUT_SECONDS: 1800s
KUBECTL_TIMEOUT_SECONDS: 60s
continue_test: true
should_cleanup: false
skip_validate: true
####################################################################################################
# Publish
####################################################################################################
publish:
needs: [build-containers, scan-containers, test-containers]
if: ${{ fromJSON(inputs.publish) }}
runs-on: ubuntu-latest # local registry label
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
with:
egress-policy: audit
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Pull Images
run: docker compose pull
working-directory: ${{ inputs.example_dir }}
- name: Push Images
run: docker compose push
working-directory: ${{ inputs.example_dir }}
- name: Cleanup
if: always()
run: |
docker logout
docker compose down
echo 'y' | docker system prune
working-directory: ${{ inputs.example_dir }}
29 changes: 0 additions & 29 deletions .github/workflows/docker/docker-compose.yaml

This file was deleted.

Loading
Loading