-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: break argus-docker-build workflow into composite actions (#283)
- Loading branch information
1 parent
2d3cc94
commit d9d1014
Showing
4 changed files
with
327 additions
and
150 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
name: argus-docker-build-prep | ||
description: Prepare for building a Docker Image for Argus | ||
|
||
inputs: | ||
path_filters: | ||
description: 'Glob patterns to match against changed files in the repository, comma delimited' | ||
required: false | ||
default: '**/*' | ||
path_filters_base: | ||
description: | | ||
Git reference (e.g. branch name) against which the changes will be detected. Defaults to the current branch. | ||
If it references same branch it was pushed to, changes are detected against the most recent commit before the push. | ||
This option is ignored if action is triggered by pull_request event. | ||
required: false | ||
default: ${{ github.ref }} | ||
branches: | ||
description: 'Branch names to run this job on, supports wildcards, comma delimited' | ||
required: false | ||
default: '*' | ||
branches_ignore: | ||
description: 'Branch names to run this job on, supports wildcards, comma delimited' | ||
required: false | ||
default: '' | ||
|
||
outputs: | ||
image_tag: | ||
description: A custom tag to apply to the images that are built | ||
value: ${{ steps.build_tags.outputs.IMAGE_TAG }} | ||
should_build: | ||
description: Whether the job should run | ||
value: ${{ steps.final_check.outputs.should_build }} | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- name: Check for matching branch | ||
id: branch_filter | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
function wildcardMatch(text, pattern) { | ||
const regexPattern = | ||
new RegExp('^' + pattern.replace(/\?/g, '.').replace(/\*/g, '.*') + '$'); | ||
return regexPattern.test(text); | ||
} | ||
const branches = `${{ inputs.branches }}`.split(',').map(b => b.trim()).filter(b => b.length > 0); | ||
console.log('Branches to run against:', branches); | ||
const branchesIgnore = `${{ inputs.branches_ignore }}`.split(',').map(b => b.trim()).filter(b => b.length > 0); | ||
console.log('Branches to ignore:', branchesIgnore); | ||
const branch = `${{ github.ref }}`.replace('refs/heads/', ''); | ||
const shouldRun = branches.some(b => wildcardMatch(branch, b)) && !branchesIgnore.some(b => wildcardMatch(branch, b)); | ||
if (shouldRun) { | ||
console.log('Job will run'); | ||
} else { | ||
console.log(`Job will be skipped because branch name "${branch}" does not match the filters`); | ||
} | ||
core.setOutput('match', shouldRun); | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Get build tag | ||
id: build_tags | ||
shell: bash | ||
run: | | ||
echo "IMAGE_TAG=sha-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT | ||
- name: Validate build tag | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const imageTag = `${{ steps.build_tags.outputs.IMAGE_TAG }}`; | ||
if (imageTag === '' || imageTag === 'sha-') { | ||
core.setFailed('The image tag [${imageTag}] is invalid.'); | ||
} | ||
- name: Parse inputs | ||
id: parse_filters | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const filters = `${{ inputs.path_filters }}`.split(',').map(f => f.trim()).filter(b => b.length > 0); | ||
const filtersStr = "run_on:\n" + filters.map(f => ` - '${f}'`).join('\n'); | ||
core.setOutput('filters', filtersStr); | ||
- name: Check for force push | ||
id: force_push | ||
uses: actions/github-script@v7 | ||
with: | ||
# if the push was forced, use the default branch as the base -- otherwise, use the most recent commit before the push | ||
# this is necessary because when you force push the previous commit is not available in the repo, thus no changes can be detected | ||
script: | | ||
if (`${{ github.event_name }}` === 'push' && ${{ github.event.forced }}) { | ||
core.info(`Force push detected, using the repo's default branch (${{ github.event.repository.default_branch }}) as the base`) | ||
core.setOutput('base', `${{ github.event.repository.default_branch }}`); | ||
} else { | ||
core.info(`Push was not forced, using the most recent commit before the push as the base`) | ||
core.setOutput('base', `${{ inputs.path_filters_base }}`); | ||
} | ||
- name: Check for matching file changes | ||
uses: dorny/paths-filter@v3 | ||
id: file_filter | ||
with: | ||
filters: | | ||
${{ steps.parse_filters.outputs.filters }} | ||
base: ${{ steps.force_push.outputs.base }} | ||
list-files: json | ||
|
||
- name: Check if build should run | ||
id: final_check | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const branchMatched = `${{ steps.branch_filter.outputs.match }}` === 'true'; | ||
const filesMatched = `${{ steps.file_filter.outputs.run_on }}` === 'true'; | ||
core.setOutput('should_build', filesMatched && branchMatched); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
name: argus-docker-build | ||
description: Build a Docker Image for Argus | ||
|
||
inputs: | ||
image_name: | ||
description: 'Name of the image to build' | ||
required: true | ||
dockerfile: | ||
description: 'Path to the Dockerfile' | ||
required: true | ||
context: | ||
description: 'Path to the build context' | ||
required: true | ||
platform: | ||
description: 'Platform to build for' | ||
required: false | ||
default: 'linux/arm64' | ||
build_args: | ||
description: 'Args for docker build' | ||
required: false | ||
default: '' | ||
image_tag: | ||
description: 'Additional tag to apply to the image this is built' | ||
required: true | ||
github_app_id: | ||
description: 'GitHub App ID' | ||
required: true | ||
github_private_key: | ||
description: 'GitHub App private key' | ||
required: true | ||
|
||
outputs: | ||
image_uri: | ||
description: 'URI of the image that was built' | ||
value: ${{ steps.ecr_metadata.outputs.IMAGE_URI }} | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
path: ${{ github.event.repository.name }} | ||
- name: Configure AWS Credentials | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
aws-region: us-west-2 | ||
role-to-assume: arn:aws:iam::533267185808:role/gh_actions_core_platform_infra_prod_eks | ||
role-session-name: ArgusContainerBuilder | ||
- name: Generate token | ||
id: generate_token | ||
uses: tibdex/github-app-token@v2 | ||
with: | ||
app_id: ${{ inputs.github_app_id }} | ||
private_key: ${{ inputs.github_private_key }} | ||
- uses: actions/checkout@v4 | ||
with: | ||
repository: chanzuckerberg/core-platform-settings | ||
path: core-platform-settings | ||
token: ${{ steps.generate_token.outputs.token }} | ||
- name: ECR Metadata | ||
id: ecr_metadata | ||
shell: bash | ||
run: | | ||
ECR_REGISTRY="533267185808.dkr.ecr.us-west-2.amazonaws.com" | ||
echo "ECR_REGISTRY=$ECR_REGISTRY" >> $GITHUB_OUTPUT | ||
ECR_REPO_NAME="core-platform/${{ github.event.repository.name }}/${{ inputs.image_name }}" | ||
echo "ECR_REPO_NAME=$ECR_REPO_NAME" >> $GITHUB_OUTPUT | ||
IMAGE_URI="$ECR_REGISTRY/$ECR_REPO_NAME:${{ inputs.image_tag }}" | ||
echo "IMAGE_URI=$IMAGE_URI" >> $GITHUB_OUTPUT | ||
- name: Create ECR repo if necessary | ||
uses: int128/create-ecr-repository-action@v1 | ||
with: | ||
repository: ${{ steps.ecr_metadata.outputs.ECR_REPO_NAME }} | ||
lifecycle-policy: core-platform-settings/ecr/lifecycle-policy.json | ||
repository-policy: core-platform-settings/ecr/repository-policy.json | ||
- name: Build And Push | ||
uses: chanzuckerberg/github-actions/.github/actions/docker-build-push@docker-build-push-v1.6.0 | ||
with: | ||
dockerfile: ${{ github.event.repository.name }}/${{ inputs.dockerfile }} | ||
context: ${{ github.event.repository.name }}/${{ inputs.context }} | ||
name: ${{ steps.ecr_metadata.outputs.ECR_REPO_NAME }} | ||
registry: ${{ steps.ecr_metadata.outputs.ECR_REGISTRY }} | ||
custom_tag: ${{ inputs.image_tag }} | ||
platforms: ${{ inputs.platform }} | ||
build_args: | | ||
IMAGE_TAG=${{ inputs.image_tag }} | ||
${{ inputs.build_args }} | ||
# TODO: scan image for vulnerabilities | ||
# - name: Scan for vulnerabilities | ||
# uses: chanzuckerberg/github-actions/.github/actions/argus-builder/scan-for-vulnerabilities@main | ||
# with: | ||
# image_uri: ${{ steps.ecr_metadata.outputs.ECR_REGISTRY }}/${{ steps.ecr_metadata.outputs.ECR_REPO_NAME }}:${{ inputs.image_tag }} | ||
# github_app_id: ${{ inputs.github_app_id }} | ||
# github_private_key: ${{ inputs.github_private_key }} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
name: argus-docker-manifest-update | ||
description: Updates manifests for Argus after the Docker image is built | ||
|
||
inputs: | ||
envs: | ||
description: 'Env names, comma delimited' | ||
required: true | ||
image_tag: | ||
description: The tag of the image that should be updated | ||
required: true | ||
working_directory: | ||
description: 'The Argus project root (parent directory that contains the .infra/ directory)' | ||
default: '.' | ||
required: false | ||
github_app_id: | ||
description: 'GitHub App ID' | ||
required: true | ||
github_private_key: | ||
description: 'GitHub App private key' | ||
required: true | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- run: | | ||
echo "Image Tag: ${{ inputs.image_tag }}" | ||
shell: bash | ||
- name: Generate token | ||
id: generate_token | ||
uses: tibdex/github-app-token@v2 | ||
with: | ||
app_id: ${{ inputs.github_app_id }} | ||
private_key: ${{ inputs.github_private_key }} | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
token: ${{ steps.generate_token.outputs.token }} | ||
- name: Parse envs | ||
id: parse_envs | ||
uses: actions/github-script@v7 | ||
with: | ||
script: | | ||
const envs = `${{ inputs.envs }}`.split(',').map(env => env.trim()).filter(b => b.length > 0); | ||
core.setOutput('envs', envs.join(' ')); | ||
- name: Determine .infra path | ||
uses: actions/github-script@v7 | ||
id: path | ||
with: | ||
script: | | ||
const path = require('path'); | ||
const fs = require('fs'); | ||
const infraDirPath = path.join(`${{ inputs.working_directory }}`, '.infra'); | ||
if (!fs.existsSync(infraDirPath)) { | ||
throw new Error(`.infra directory not found at ${infraDirPath}`); | ||
} | ||
core.setOutput('infra_dir_path', infraDirPath); | ||
- name: Update Manifest | ||
shell: bash | ||
run: | | ||
for env in ${{ steps.parse_envs.outputs.envs }} | ||
do | ||
sed -i 's/tag: sha-\w\+/tag: ${{ inputs.image_tag }}/g' ${{ steps.path.outputs.infra_dir_path }}/${env}/values.yaml | ||
cat ${{ steps.path.outputs.infra_dir_path }}/${env}/values.yaml | ||
done | ||
- name: Update Argus manifests | ||
uses: EndBug/add-and-commit@v9 | ||
with: | ||
add: -A | ||
message: 'chore: Updated [${{ steps.parse_envs.outputs.envs }}] values.yaml image tags to ${{ inputs.image_tag }}' | ||
|
Oops, something went wrong.