Skip to content

Build Release

Build Release #296

Workflow file for this run

---
name: "Build Release"
on:
workflow_dispatch:
inputs:
releaseBranch:
description: >-
releaseBranch: Override the branch on which a release is based.
Default to the selected reference in the `Use workflow from` drop-down when empty.
required: false
default: ""
releaseVersion:
description: >-
releaseVersion: Override the release version. Default to promoting the current
X.Y.Z-SNAPSHOT to X.Y.Z when empty.
required: false
default: ""
developmentVersion:
description: >-
developmentVersion: Override the next development iteration version.
Default to X.(Y+1).0-SNAPSHOT of the release version X.Y.Z when empty.
required: false
default: ""
awsRegion:
description: >-
awsRegion: Override the AWS Region destination for uploaded artifacts.
Default to `us-east-1`.
default: us-east-1
type: choice
options:
- us-east-1
- us-west-2
required: true
forceRelease:
description: >-
forceRelease: Override creation of the GitHub Release object.
Default to creating release objects when `releaseVersion` does not contain the hyphen
character ('-'), indicating a pre-release.
default: false
required: false
type: boolean
workflow_call:
inputs:
releaseBranch:
type: string
description: >-
releaseBranch: Override the branch on which a release is based.
Default to the selected reference in the `Use workflow from` drop-down when empty.
required: false
default: ""
releaseVersion:
type: string
description: >-
releaseVersion: Override the release version. Default to promoting the current
X.Y.Z-SNAPSHOT to X.Y.Z when empty.
required: false
default: ""
developmentVersion:
type: string
description: >-
developmentVersion: Override the next development iteration version.
Default to X.(Y+1).0-SNAPSHOT of the release version X.Y.Z when empty.
required: false
default: ""
awsRegion:
type: string
description: >-
awsRegion: Override the AWS Region destination for uploaded artifacts.
Default to `us-east-1`.
default: us-east-1
required: true
forceRelease:
type: boolean
description: >-
forceRelease: Override creation of the GitHub Release object.
Default to creating release objects when `releaseVersion` does not contain the hyphen
character ('-'), indicating a pre-release.
default: false
required: false
outputs:
bfd_release:
description: The BFD release version that corresponds to the Git tag and GitHub release
value: ${{ jobs.compute-version-strings.outputs.bfd_release }}
bfd_dev_version:
description: The BFD snapshot development version that corresponds to the next release version
value: ${{ jobs.compute-version-strings.outputs.bfd_dev_version }}
permissions:
id-token: write # This is required for requesting the AWS IAM OIDC JWT
contents: write # This is required for actions/checkout
env:
AWS_REGION: ${{ inputs.awsRegion }}
BFD_RELEASE_OVERRIDE: ${{ inputs.releaseVersion }}
BFD_DEV_VERSION_OVERRIDE: ${{ inputs.developmentVersion }}
JIB_IMAGES: |
[
"bfd-server",
"bfd-server-ng",
"bfd-pipeline-app",
"bfd-db-migrator"
]
ACCOUNT_ROLE_MAP: |
{
"prod": "${{ secrets.PROD_ACCOUNT_GHA_ROLE_ARN }}",
"non-prod": "${{ secrets.NON_PROD_ACCOUNT_GHA_ROLE_ARN }}"
}
defaults:
run:
shell: bash
jobs:
compute-version-strings:
runs-on: ubuntu-24.04
outputs:
bfd_release: ${{ steps.bfd-version-strings.outputs.BFD_RELEASE }}
bfd_dev_version: ${{ steps.bfd-version-strings.outputs.BFD_DEV_VERSION }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ inputs.releaseBranch || github.ref_name }}
- name: "Install yq"
run: |
sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq
sudo chmod +x /usr/bin/yq
- name: Set and Validate Version Strings
id: bfd-version-strings
run: |
# Set default values for bfd-parent version based on existing version string in apps/pom.xml
BFD_PARENT_POM_VERSION="$(yq --output-format=yaml .project.version apps/pom.xml)"
## Use override OR promote default by removing '-SNAPSHOT' suffix
BFD_RELEASE_DEFAULT="$(yq 'split("-") | .[0]' <<< "$BFD_PARENT_POM_VERSION")"
BFD_RELEASE="${BFD_RELEASE_OVERRIDE:-$BFD_RELEASE_DEFAULT}"
## Use override OR increment default value Y in X.Y.Z formatted release version, attach '-SNAPSHOT' suffix
BFD_DEV_VERSION_DEFAULT="$(yq 'split("-") | .[0] | split(".") | map(. type = "!!int") | [.[0], .[1]+1, .[2]] | join(".")' <<< "$BFD_PARENT_POM_VERSION")-SNAPSHOT"
BFD_DEV_VERSION="${BFD_DEV_VERSION_OVERRIDE:-$BFD_DEV_VERSION_DEFAULT}"
# Validate and set BFD_RELASE and BFD_DEV_VERSION
echo "$BFD_RELEASE" | grep -P '^\d+\.\d+\.\d+$|^\d+\.\d+\.\d+-[a-zA-Z0-9-]+$'
echo BFD_RELEASE="${BFD_RELEASE}" >> "$GITHUB_OUTPUT"
echo "$BFD_DEV_VERSION" | grep -P '^\d+\.\d+\.\d+-SNAPSHOT$'
echo BFD_DEV_VERSION="${BFD_DEV_VERSION_OVERRIDE:-$BFD_DEV_VERSION_DEFAULT}" >> "$GITHUB_OUTPUT"
# build-base-images:
# uses: ./.github/workflows/build-container-images.yml
# needs: compute-version-strings
# permissions:
# contents: read
# id-token: write
# with:
# branch: ${{ inputs.releaseBranch || github.ref_name }}
# versionTag: ${{ needs.compute-version-strings.outputs.bfd_release }}
# awsRegion: ${{ inputs.awsRegion }}
# # Build the base images prior to building the application images with jib in "run-mvn-release"
# # See .github/workflows/build_container_images_matrix.json for list of buildable images
# imagesCsv: "bfd-platform-base-java, bfd-platform-base-python"
# cleanupImageArtifacts: false # Keep the built images around so that they can be used for Jib
# skipBasePull: true # We're building the base images, so don't pull them
# tagLatest: ${{ !contains(needs.compute-version-strings.outputs.bfd_release, '-') }}
# secrets: inherit
run-mvn-release:
runs-on: ubuntu-24.04-arm
needs: [compute-version-strings]
env:
BFD_RELEASE: ${{ needs.compute-version-strings.outputs.bfd_release }}
BFD_DEV_VERSION: ${{ needs.compute-version-strings.outputs.bfd_dev_version }}
steps:
- name: "Generate an App Token"
id: generate_token
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
with:
app-id: ${{ secrets.BFD_RELEASE_APP_ID }}
private-key: ${{ secrets.BFD_RELEASE_APP_KEY }}
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ inputs.releaseBranch || github.ref_name }}
token: ${{ steps.generate_token.outputs.token }}
# - name: Retrieve base java image
# uses: actions/download-artifact@v8
# with:
# pattern: '*bfd-platform-base-java*'
# merge-multiple: true
# path: ${{ runner.temp }}
# - name: Load base image into Docker
# run: |
# docker load --input "${{ runner.temp }}/bfd-platform-base-java.tar"
# - name: Install gitleaks
# run: |
# curl -s https://api.github.com/repos/gitleaks/gitleaks/releases/latest \
# | grep "browser_download_url.*linux_x64.tar.gz" \
# | cut -d : -f 2,3 \
# | tr -d \" \
# | wget -qi -
# sudo tar -xzf "$(find -iname 'gitleaks*.tar.gz')" -C /usr/bin gitleaks
# sudo chmod +x /usr/bin/gitleaks
- name: Setup JDK
uses: actions/setup-java@v5
with:
java-version: "25"
distribution: corretto
- name: Configure the git user
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
# - name: Configure additional maven settings.xml
# run: |-
# cat <<"EOF" > ~/.m2/settings.xml
# <settings xmlns="http://maven.apache.org/settings/1.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
# xsi:schemalocation="http://maven.apache.org/settings/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
# <servers>
# <server>
# <id>github</id>
# <username>${env.GITHUB_ACTOR}</username>
# <password>${env.GITHUB_TOKEN}</password>
# </server>
# </servers>
# </settings>
# EOF
# - name: "Prepare Release"
# run: |-
# # We set preparationGoals to an empty string because we don't want to build during the
# # release:prepare since we will need to build again during release:perform. We expect that the
# # source code has been verified to compile and pass tests prior to merging to master, so building it
# # unnecessarily during the prepare phase is redundant.
# mvn --batch-mode --activate-profiles prepare-release \
# -Dtag="$BFD_RELEASE" \
# -DreleaseVersion="$BFD_RELEASE" \
# -DdevelopmentVersion="$BFD_DEV_VERSION" \
# -DpreparationGoals="" \
# release:prepare
# working-directory: ./apps
# env:
# GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
# - name: "Perform Release"
# run: |-
# mvn --batch-mode --activate-profiles perform-release \
# -Dtag="$BFD_RELEASE" \
# -DreleaseVersion="$BFD_RELEASE" \
# -DdevelopmentVersion="$BFD_DEV_VERSION" \
# release:perform
# working-directory: ./apps
# env:
# GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
# - name: Export jib images
# run: |
# readarray -t images < <(echo "$JIB_IMAGES" | jq -r -c '.[]')
# for image in "${images[@]}"
# do
# docker save "$image:$BFD_RELEASE" > "${image}.tar"
# done
# working-directory: ${{ runner.temp }}
# - name: Upload jib image artifacts
# uses: actions/upload-artifact@v7
# with:
# name: jib-images
# path: ${{ runner.temp }}/*.tar
# retention-days: 1
# - name: Get bfd-server-war m2 directory
# id: get-server-war-dir
# run: |
# server_war_dir="$(realpath "$(find ~/.m2/repository -type d -path '*/bfd-server-war/*' | head -n1)")"
# ls "$server_war_dir"
# echo "server-war-dir=$server_war_dir" >> "$GITHUB_OUTPUT"
- name: Install node
uses: actions/setup-node@v6
with:
node-version: "22"
- name: Install Sushi
run: |
npm install -g fsh-sushi
sushi build
echo "Installed + run sushi"
working-directory: apps/bfd-model-idr/sushi
- name: Install fhirpath
run: |
npm install fhirpath
working-directory: apps/bfd-model-idr
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
version: "0.11.2"
- name: Install UV dependencies
run: uv sync
working-directory: apps/bfd-model-idr
- name: Generate v3 Data Dictionary
run: uv run gen_dd.py
working-directory: apps/bfd-model-idr
- name: Prepare artifacts
env:
BFD_RELEASE: ${{ needs.compute-version-strings.outputs.bfd_release }}
run: |
set -euo pipefail
shopt -s nullglob
mkdir -p assets
echo "Preparing server WAR artifacts..."
# 1) Handle v1/v2 artifacts
# for artifact_path in ${{ steps.get-server-war-dir.outputs.server-war-dir }}/*
# do
# filename="$(basename -- "$artifact_path")"
# if [[ "$filename" =~ ^bfd-server-war-$BFD_RELEASE-(.+)$ ]]; then
# artifact="${BASH_REMATCH[1]}"
# artifact_ext="${artifact#*.}"
# artifact_name="${artifact%%.*}"
# cp "$artifact_path" "assets/${artifact_name}-${BFD_RELEASE}.${artifact_ext}"
# fi
# done
# TODO: Re-enable this once BFD v3 DD generation is fixed
echo "Preparing data dictionary artifacts..."
# # 2) Handle v3 artifacts
for artifact_path in apps/bfd-model-idr/out/bfd_data_dictionary.*
do
filename="$(basename -- "$artifact_path")"
artifact_ext="${filename#*.}"
cp "$artifact_path" "assets/v3-data-dictionary-${BFD_RELEASE}.${artifact_ext}"
done
echo "Final staged artifacts:"
ls -l assets
- name: Upload release artifacts
uses: actions/upload-artifact@v7
with:
name: release-artifacts
path: assets/*
retention-days: 1
# - name: "Perform Exceptional Rollback"
# if: failure()
# run: mvn release:rollback
# working-directory: ./apps
# push-jib-images:
# needs: [compute-version-strings, run-mvn-release]
# strategy:
# matrix:
# account: ["prod", "non-prod"]
# runs-on: codebuild-bfd-${{ matrix.account }}-platform-docker-${{ github.run_id }}-${{ github.run_attempt }}
# env:
# BFD_RELEASE: ${{ needs.compute-version-strings.outputs.bfd_release }}
# BFD_DEV_VERSION: ${{ needs.compute-version-strings.outputs.bfd_dev_version }}
# steps:
# - name: Get role ARN
# id: get-role-arn
# run: |
# role_arn="$(jq -r --arg account_type "${{ matrix.account }}" '.[$account_type]' <<<"$ACCOUNT_ROLE_MAP")"
# echo "::add-mask::$role_arn"
# echo "role-arn=$role_arn" >> "$GITHUB_OUTPUT"
# - name: Download jib image artifacts
# uses: actions/download-artifact@v8
# with:
# name: jib-images
# path: ${{ runner.temp }}
# - name: Configure AWS credentials
# uses: aws-actions/configure-aws-credentials@v6
# with:
# role-to-assume: ${{ steps.get-role-arn.outputs.role-arn }}
# role-session-name: build-release-${{ github.run_id }}-${{ github.run_attempt }}
# aws-region: ${{ env.AWS_REGION }}
# - name: Login to ECR
# id: ecr-login
# uses: aws-actions/amazon-ecr-login@v2
# - name: Push jib images
# env:
# REGISTRY: ${{ steps.ecr-login.outputs.registry }}
# PUSH_LATEST: ${{ !contains(needs.compute-version-strings.outputs.bfd_release, '-') }}
# run: |
# echo "::add-mask::$REGISTRY"
# for image_filename in ./*.tar
# do
# docker load --input "$image_filename"
# image="$(basename "$image_filename" .tar)"
# docker tag "$image:$BFD_RELEASE" "$REGISTRY/$image:$BFD_RELEASE"
# if [[ $PUSH_LATEST == "true" ]]; then
# # Remove the "latest" tag from the existing latest image
# aws ecr batch-delete-image --repository-name "$image" --image-ids imageTag=latest &>/dev/null || true
# # Tag the new release image as "latest"
# docker tag "$image:$BFD_RELEASE" "$REGISTRY/$image:latest"
# # Push "latest" tag
# docker push "$REGISTRY/$image:latest"
# fi
# docker push "$REGISTRY/$image:$BFD_RELEASE"
# done
# working-directory: ${{ runner.temp }}
# build-other-images:
# uses: ./.github/workflows/build-container-images.yml
# needs: [compute-version-strings, run-mvn-release]
# permissions:
# contents: read
# id-token: write
# with:
# branch: ${{ inputs.releaseBranch || github.ref_name }}
# versionTag: ${{ needs.compute-version-strings.outputs.bfd_release }}
# awsRegion: ${{ inputs.awsRegion }}
# # Build other images, like Lambda images, Python applications, etc.
# # See .github/workflows/build_container_images_matrix.json for list of buildable images
# imagesCsv: >-
# bfd-platform-server-regression,
# bfd-platform-mount-certstores,
# bfd-platform-server-fluent-bit,
# bfd-platform-idr-pipeline,
# bfd-platform-migrator-ng,
# bfd-platform-run-locust,
# bfd-platform-eft-sftp-outbound-transfer-lambda,
# bfd-platform-pipeline-ccw-manifests-verifier-lambda,
# bfd-platform-pipeline-ccw-runner,
# bfd-platform-consume-idr-events,
# bfd-platform-run-idr-pipeline,
# bfd-platform-codebuild-runner
# baseImagesVersion: ${{ needs.compute-version-strings.outputs.bfd_release }}
# cleanupImageArtifacts: false # We'll cleanup at the end of build-release, so don't do anything
# tagLatest: ${{ !contains(needs.compute-version-strings.outputs.bfd_release, '-') }}
# secrets: inherit
# create-gh-release:
# if: ${{ !contains(needs.compute-version-strings.outputs.bfd_release, '-') || inputs.forceRelease }}
# runs-on: ubuntu-24.04
# needs:
# [
# compute-version-strings,
# build-base-images,
# run-mvn-release,
# push-jib-images,
# build-other-images,
# ]
# steps:
# - name: Pull release artifacts
# id: pull-release-artifacts
# uses: actions/download-artifact@v8
# with:
# name: release-artifacts
# - name: Release
# uses: ncipollo/release-action@v1
# with:
# # NOTE: Prevent automatic promotion of pre-release objects to latest
# makeLatest: "${{ !contains(needs.compute-version-strings.outputs.bfd_release, '-') }}"
# generateReleaseNotes: true
# artifactErrorsFailBuild: true
# tag: ${{ needs.compute-version-strings.outputs.bfd_release }}
# name: "v${{ needs.compute-version-strings.outputs.bfd_release }}"
# artifacts: "*.csv,*.json,*.xlsx,*.yaml"
# cleanup-artifacts:
# if: ${{ !cancelled() }}
# needs: [build-other-images, create-gh-release]
# runs-on: ubuntu-24.04
# steps:
# - name: Delete all artifacts
# uses: GeekyEggo/delete-artifact@176a747ab7e287e3ff4787bf8a148716375ca118 # v6
# with:
# name: '*'
# failOnError: false