Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
174 changes: 174 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
name: "Build Docker Image"

on:
workflow_call:
inputs:
tag:
description: Revision, tag, or branch to build
required: true
type: string
default: ${{ github.event.repository.default_branch }}
img_tag:
description: Tag applied to the container image.
type: string
image:
description: >-
Image to build, e.g. ghcr.io/organization/image.
required: true
type: string
registry:
description: >-
Registry that hosts these images; by default, ghcr.io.
default: ghcr.io
type: string
registry_username:
description: >-
Username for logging in to registry. For GHCR (and by default), set to github.actor.
default: ${{ github.actor }}
type: string
registry_token:
description: >-
Token for logging in to registry. For GHCR (and by default), set to github.token.
default: ${{ github.token }}
type: string
build-args:
description: >-
Set build time variables for the ARG instruction
required: false
type: string
dockerfile:
description: >-
Which file to use to build the image; by default, Dockerfile
default: Dockerfile
type: string
push_latest:
description: >-
Update 'latest' tag when pushing
default: false
type: boolean
submodules:
description: >-
Whether to checkout submodules (as for actions@v3) and thence build them into the image. Set to false by default as for checkout. If you use submodules, you probably want to set this.
default: false
type: boolean
platforms:
description: >-
Build images for cross platform support.
default: "linux/amd64,linux/arm64"
type: string
rebuild:
description: Rebuild the image manually?
default: false
type: boolean
gh_event:
description: The name of the event that triggered the parent workflow.
type: string
target:
description: Sets the target stage to build
type: string

outputs:
ghc_img:
description: "Export GHCR.io package resource URL"
value: ${{ jobs.build.result.ghc_img_id.outputs.ghc_img }}

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Set Inputs & Outputs
id: set_inputs
shell: bash
run: |
if [ "${{ github.event_name }}" == "workflow_run" ]; then
echo "ref=${{ github.sha }}" >> $GITHUB_OUTPUT
echo "push_latest=true" >> $GITHUB_OUTPUT
else
# workflow_dispatch or other trigger
echo "ref=${{ inputs.tag }}" >> $GITHUB_OUTPUT
echo "push_latest=${{ inputs.push_latest }}" >> $GITHUB_OUTPUT
echo "img_tag=${{ inputs.img_tag }}" >> $GITHUB_OUTPUT
fi

- name: Clone latest repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ steps.set_inputs.outputs.ref }}
submodules: ${{ inputs.submodules }}

- name: Find commit for tag
id: tag_check
uses: hathitrust/github_actions/validate-tag@v1
with:
tag: ${{ steps.set_inputs.outputs.ref }}

- name: Log into container registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
registry: ${{ inputs.registry }}
username: ${{ inputs.registry_username }}
password: ${{ inputs.registry_token }}

- name: Check if revision exists in container registry
id: image_check
shell: bash
run: |
echo Checking whether Docker image "$IMAGE":"$TAG" exists
if docker manifest inspect "$IMAGE":"$TAG" > /dev/null; then
echo 'image_exists=true' >> $GITHUB_OUTPUT
echo "image exists!"
else
echo "image doesn't exist; Starting to Build and push image"
fi
env:
IMAGE: ${{ inputs.image }}
TAG: ${{ steps.tag_check.outputs.tag }}

- name: Check whether to push latest tag
if: ${{ steps.image_check.outputs.image_exists != 'true' || inputs.rebuild }}
id: latest_push
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
INPUT_PUSH_LATEST: ${{ steps.set_inputs.outputs.push_latest }}
INPUT_IMAGE: ${{ inputs.image }}
with:
script: |
if ( core.getInput('push_latest') == 'true' ) {
core.setOutput('latest_tag',core.getInput('image') + ':latest')
} else {
core.setOutput('latest_tag',core.getInput('image') + ':unstable')
}

- name: Set up QEMU
if: ${{ steps.image_check.outputs.image_exists != 'true' || inputs.rebuild }}
# QEMU emulation for the Arm portion of our multi-platform Docker image build. Intel Machines
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0

- name: Set up Docker Buildx
if: ${{ steps.image_check.outputs.image_exists != 'true' || inputs.rebuild }}
# Required for multi-platform Docker image builds in GitHub Actions that use docker/build-push-action.
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0

- name: Build image and push to GHCR
if: ${{ steps.image_check.outputs.image_exists != 'true' || inputs.rebuild }}
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
with:
context: .
push: true
tags: |
${{ inputs.image }}:${{ steps.set_inputs.outputs.img_tag && inputs.img_tag || steps.tag_check.outputs.tag }}
${{ inputs.image }}:${{ steps.tag_check.outputs.tag }}
${{ steps.latest_push.outputs.latest_tag }}
file: ${{ inputs.dockerfile }}
build-args: ${{ inputs.build-args }}
platforms: ${{ inputs.platforms}}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
pull: true
target: ${{inputs.target}}

- name: Export GHCR.io resource
id: ghc_img_id
shell: bash
run: echo "ghc_img=${{ inputs.image }}:${{ steps.tag_check.outputs.tag }}" >> $GITHUB_OUTPUT
76 changes: 76 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Deploy
# description: This is action is used to deploy.

on:
workflow_call:
inputs:
environment:
required: false
description: the github actions environment context
type: string
image:
required: true
description: The full gchr image
type: string
file:
required: true
description: path to file in repository to update with the image
type: string
CONFIG_REPO_RW_APP_ID:
description: The ID of the GithubApp that is used to generate keys that enable one repository to send repository dispatch messages to another.
required: true
type: string
CONFIG_REPO_RW_INSTALL_ID:
description: ""
required: false
type: string
CONFIG_REPO_FULL_NAME:
description: The github repo of the tanka control repository
required: true
type: string
# secrets:
CONFIG_REPO_RW_KEY:
description: The private key used to talk to the GithubAPP with the App ID
required: true
type: string

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Set environment variables
shell: bash
run: |
if [ -z "${{ inputs.CONFIG_REPO_RW_APP_ID }}" ]
then
echo "CONFIG_REPO_RW_APP_ID=${{ env.CONFIG_REPO_RW_APP_ID }}" >> $GITHUB_ENV
echo "setting CONFIG_REPO_RW_APP_ID to ${{ env.CONFIG_REPO_RW_APP_ID }} from env"
else
echo "CONFIG_REPO_RW_APP_ID=${{ inputs.CONFIG_REPO_RW_APP_ID }}" >> $GITHUB_ENV
echo "setting CONFIG_REPO_RW_APP_ID to ${{ inputs.CONFIG_REPO_RW_APP_ID }} from inputs"
fi
if [ -z "${{ inputs.CONFIG_REPO_FULL_NAME }}" ]
then
echo "CONFIG_REPO_FULL_NAME=${{ env.CONFIG_REPO_FULL_NAME }}" >> $GITHUB_ENV
echo "setting CONFIG_REPO_FULL_NAME to ${{ env.CONFIG_REPO_FULL_NAME }} from env"
else
echo "CONFIG_REPO_FULL_NAME=${{ inputs.CONFIG_REPO_FULL_NAME }}" >> $GITHUB_ENV
echo "setting CONFIG_REPO_FULL_NAME to ${{ inputs.CONFIG_REPO_FULL_NAME }} from inputs"
fi
- name: Generate app token
id: generate_token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ env.CONFIG_REPO_RW_APP_ID }}
private-key: ${{ inputs.CONFIG_REPO_RW_KEY }}
owner: ${{ github.repository_owner }}
- name: Send the message
uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v4.0.1
with:
event-type: update-image
token: ${{ steps.generate_token.outputs.token }}
repository: ${{ env.CONFIG_REPO_FULL_NAME }}
client-payload: '{ "subject": "Update ${{ inputs.file }}", "body": "Originating repository is ${{ github.repository }}\nRun ID is ${{ github.run_id }}\nUser is ${{ github.actor }}", "image": "${{ inputs.image }}", "file": "${{ inputs.file }}" }'
71 changes: 71 additions & 0 deletions .github/workflows/scan-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: "Vulnerability Scan on Docker Image"
#description: "This uses Trivy to run a security scan on a docker image"

on:
workflow_call:
inputs:
image-ref:
description: Image reference
required: true
type: string
latest:
description: Skip calling the setup-trivy action to install trivy
default: "false"
type: string

jobs:
image-scan:
runs-on: ubuntu-latest
steps:
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
env:
TRIVY_DISABLE_VEX_NOTICE: true
with:
image-ref: ${{ inputs.image-ref }}
format: "table" # Output format (table, json, template, sarif, cyclonedx, spdx, spdx-json, github, cosign-vuln)
exit-code: "0" # Exit code for runner when a vulnerability is found. Non-0 exit will fail the job
ignore-unfixed: true # Ignore unpatched/unfixed vulnerabilities
vuln-type: "os,library"
severity: "CRITICAL,HIGH,MEDIUM" # UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL
cache: "true" # By default, cache is only accessed within the current branch.
output: trivy-report.txt

- name: Publish Trivy Output to Summary
id: trivy-summary
shell: bash
run: |
if [[ -s trivy-report.txt ]]; then
{
echo "### Security Output"
echo "<details><summary>Click to expand</summary>"
echo ""
echo '```'
cat trivy-report.txt
echo '```'
echo "</details>"
} >> $GITHUB_STEP_SUMMARY
fi

- name: Comment on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const fs = require('fs')
const path = 'trivy-report.txt'
const issueComment = (content) => {
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '```'+content+'```'
})
}

try {
const content = fs.readFileSync(path, 'utf8')
issueComment(content);
} catch (error) {
issueComment(error)
}
Loading