Rust CI/CD #3
Workflow file for this run
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
# A common workflow for building, testing and publishing docker images in the samply organization (see https://github.com/samply). | ||
# Upon completion of this workflow, following actions will be taken: | ||
# 1) Build the docker image using a Dockerfile in the source code (default is ./Dockerfile) | ||
# 2) Scan the image for vulnerabilities with trivy (see https://github.com/aquasecurity/trivy) | ||
# 3) Upload the scan results from step 2 to the github security tab of the repository | ||
# 4) Generating appropriate image tags for publishing using the docker/metadata-action. Following Rules are applied: | ||
# 1. Running the action on push to the main branch will trigger tagging image as latest | ||
# 2. Running the action on push to a git branch trigger tagging image as "<branchname>" | ||
# 3. Running the action on push of a git tag matching the semver schema will trigger tagging image with {MAJOR}, {MAJOR}.{MINOR} and {MAJOR}.{MINOR}.{PATCH} | ||
# 4. Running the action on push to a pull request, will trigger tagging for the github container registry with ghcr.io/<repository-name>/<pr-reference>. This will be skipped for private repositories. | ||
# 5. Running the action on a scheduled basis will trigger tagging images with "nightly". | ||
# 5) Rebuild the image for all necessary platforms an publish it based on the applied tags from 4. | ||
# | ||
# An usage example for this action is provided in the samply organization: https://github.com/samply/.github/blob/main/workflow-templates/docker-ci-template.yml | ||
name: Build, Test and Deploy Docker Image | ||
on: | ||
workflow_call: | ||
inputs: | ||
# The Docker Hub Repository you want eventually push to, e.g samply/share-client | ||
image-name: | ||
required: true | ||
type: string | ||
# Define special prefixes for docker tags | ||
image-tag-prefix: | ||
required: false | ||
type: string | ||
# Define special suffixes for docker tags | ||
image-tag-suffix: | ||
required: false | ||
type: string | ||
# Define the build context of your image, typically default '.' will be enough | ||
build-context: | ||
required: false | ||
type: string | ||
default: '.' | ||
# Define the Dockerfile of your image, typically default './Dockerfile' will be enough | ||
build-file: | ||
required: false | ||
type: string | ||
default: './Dockerfile' | ||
build-platforms: | ||
required: false | ||
type: string | ||
default: "linux/amd64,linux/arm64/v8" | ||
build-platforms-short: | ||
required: false | ||
type: string | ||
# A list of build arguments, passed to the docker build | ||
# FIXME: GitHub Actions currently doesn't support list types on inputs. This needs to be parsed by us from string. | ||
build-args: | ||
required: false | ||
type: string | ||
# If your actions generate an artifact in a previous build step, you can tell this worflow to download it. | ||
# '*' will download *ALL* build artifacts into named subdirectories. | ||
artifact-name: | ||
required: false | ||
type: string | ||
default: '' | ||
binary-name: | ||
required: false | ||
type: string | ||
# Set to none, dockerhub, ghcr or both | ||
push-to: | ||
required: true | ||
type: string | ||
secrets: | ||
DOCKERHUB_USERNAME: | ||
required: true | ||
DOCKERHUB_TOKEN: | ||
required: true | ||
jobs: | ||
tidy-ghcr: | ||
name: Tidy GHCR | ||
runs-on: ubuntu-latest | ||
uses: actions/delete-package-versions@v5 | ||
with: | ||
package-name: ${{ inputs.image-name }} | ||
package-type: 'container' | ||
min-versions-to-keep: 10 | ||
build: | ||
name: Dockerize${{ inputs.binary-name && format(' ({0})', inputs.binary-name) }}${{ inputs.image-tag-suffix && format(' ({0})', inputs.image-tag-suffix) }} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Read vars | ||
env: | ||
ARCHS_LONG: ${{ inputs.build-platforms }} | ||
ARCHS_SHORT: ${{ inputs.build-platforms-short }} | ||
PUSH_TO: ${{ inputs.push-to }} | ||
run: | | ||
RESULT="" | ||
if [ "$ARCHS_SHORT" == "" ]; then | ||
RESULT="$ARCHS_LONG" | ||
else | ||
for ARCH in $(echo "$ARCHS_SHORT" | jq -r '.[]'); do | ||
if [ "$ARCH" == "amd64" ]; then | ||
RESULT="$RESULT,linux/amd64" | ||
fi | ||
if [ "$ARCH" == "arm64" ]; then | ||
RESULT="$RESULT,linux/arm64/v8" | ||
fi | ||
done | ||
fi | ||
GHCR= | ||
DOCKERHUB= | ||
case "$PUSH_TO" in | ||
both) | ||
GHCR=true | ||
DOCKERHUB=true | ||
;; | ||
dockerhub) | ||
DOCKERHUB=true | ||
;; | ||
ghcr) | ||
GHCR=true | ||
;; | ||
none) | ||
;; | ||
*) | ||
echo "Unsupported push target: \"$PUSH_TO\". Please supply none, dockerhub, ghcr or both." | ||
exit 1 | ||
esac | ||
echo "Resulting build_platforms is \"$RESULT\"" | ||
echo "build_platforms=$RESULT" >> $GITHUB_ENV | ||
echo "dockerhub=$DOCKERHUB" >> $GITHUB_ENV | ||
echo "ghcr=$GHCR" >> $GITHUB_ENV | ||
- name: Analyze repository | ||
run: | | ||
VISIBILITY="$(curl https://api.github.com/repos/${{ github.repository }} | jq -r .visibility)" | ||
if [ "$VISIBILITY" != "public" ]; then | ||
echo "Repository is not public -- will skip security scans and push to github container registry." | ||
echo "security-scan=false" >> $GITHUB_ENV | ||
else | ||
echo "security-scan=true" >> $GITHUB_ENV | ||
fi | ||
- name: Checkout Source Code | ||
uses: actions/checkout@v2 | ||
- name: Download specific Build Artifact to artifacts/ | ||
if: ${{ inputs.artifact-name != '' && inputs.artifact-name != '*' }} | ||
uses: actions/download-artifact@v3 | ||
with: | ||
name: ${{ inputs.artifact-name }} | ||
path: artifacts | ||
- name: Download all Build Artifacts to artifacts/ | ||
if: ${{ inputs.artifact-name == '*' }} | ||
uses: actions/download-artifact@v3 | ||
with: | ||
path: artifacts | ||
- name: Replace binary name in Dockerfile | ||
if: ${{ inputs.binary-name }} | ||
env: | ||
BUILD_FILE: ${{ inputs.build-file }} | ||
BINARY_NAME: ${{ inputs.binary-name }} | ||
run: | | ||
sed -i "s,/usr/local/bin/samply,/usr/local/bin/${BINARY_NAME},g" ${BUILD_FILE} | ||
- name: ls | ||
run: ls -laR | ||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@v1 | ||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v1 | ||
- name: Build and Export to Docker | ||
uses: docker/build-push-action@v2 | ||
with: | ||
context: ${{ inputs.build-context }} | ||
file: ${{ inputs.build-file }} | ||
build-args: ${{ inputs.build-args }} | ||
# NOTE: Not specifying build platforms here due to conflict with the load option! | ||
load: true | ||
tags: ${{ inputs.image-name }} | ||
- name: Run Trivy Vulnerability Scanner | ||
uses: aquasecurity/trivy-action@master | ||
if: ${{ env.security-scan != 'false' }} | ||
with: | ||
image-ref: ${{ inputs.image-name }} | ||
format: sarif | ||
timeout: '10m0s' | ||
ignore-unfixed: true | ||
output: trivy-results.sarif | ||
- name: Upload Trivy Scan Results to GitHub Security Tab | ||
uses: github/codeql-action/upload-sarif@codeql-bundle-20211208 | ||
if: ${{ env.security-scan != 'false' }} | ||
with: | ||
sarif_file: trivy-results.sarif | ||
- name: Define Image Tags for Github Container Registry | ||
id: docker-meta-ghcr | ||
if: env.ghcr | ||
uses: docker/metadata-action@v3 | ||
with: | ||
images: | | ||
"ghcr.io/${{ inputs.image-name }}" | ||
tags: | | ||
type=schedule | ||
type=ref,event=branch | ||
type=ref,event=pr,prefix=${{ inputs.image-tag-prefix }},suffix=${{ inputs.image-tag-suffix }}pr- | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
type=semver,pattern={{major}} | ||
type=sha,format=long,prefix=${{ inputs.image-tag-prefix }},suffix=${{ inputs.image-tag-suffix }}sha- | ||
# set latest tag for default branch | ||
type=raw,value=latest,enable={{is_default_branch}} | ||
flavor: | | ||
prefix=${{ inputs.image-tag-prefix }},onlatest=true | ||
suffix=${{ inputs.image-tag-suffix }},onlatest=true | ||
- name: Login to Github Container Registry | ||
if: env.ghcr | ||
uses: docker/login-action@v1 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Build and Push Image to Github Container Registry | ||
if: env.ghcr | ||
uses: docker/build-push-action@v2 | ||
with: | ||
context: ${{ inputs.build-context }} | ||
file: ${{ inputs.build-file }} | ||
push: true | ||
platforms: ${{ env.build_platforms }} | ||
build-args: ${{ inputs.build-args }} | ||
labels: ${{ steps.docker-meta-ghcr.outputs.labels }} | ||
tags: ${{ steps.docker-meta-ghcr.outputs.tags }} | ||
- name: Generate Image Tags for Docker Hub | ||
id: docker-meta | ||
uses: docker/metadata-action@v3 | ||
if: env.dockerhub | ||
with: | ||
images: | | ||
${{ inputs.image-name }} | ||
tags: | | ||
type=schedule | ||
type=ref,event=branch | ||
type=semver,pattern={{version}} | ||
type=semver,pattern={{major}}.{{minor}} | ||
type=semver,pattern={{major}} | ||
# set latest tag for default branch | ||
type=raw,value=latest,enable={{is_default_branch}} | ||
flavor: | | ||
prefix=${{ inputs.image-tag-prefix }},onlatest=true | ||
suffix=${{ inputs.image-tag-suffix }},onlatest=true | ||
- name: Login to Docker Hub | ||
uses: docker/login-action@v1 | ||
if: env.dockerhub | ||
with: | ||
username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
- name: Build and Push Image to Docker Hub | ||
uses: docker/build-push-action@v2 | ||
if: env.dockerhub | ||
with: | ||
context: ${{ inputs.build-context }} | ||
file: ${{ inputs.build-file }} | ||
push: true | ||
platforms: ${{ env.build_platforms }} | ||
build-args: ${{ inputs.build-args }} | ||
tags: ${{ steps.docker-meta.outputs.tags }} | ||
labels: ${{ steps.docker-meta.outputs.labels }} | ||