Skip to content
name: Create and upload packer generated images
on:
push:
branches:
- lma/release/tags
workflow_dispatch:
inputs:
node_version:
description: "The version of Concordium node to built from. Format: x.y.z-q"
required: true
type: string
release_type:
description: "The release type "
required: true
type: choice
options:
- alpha
- rc
# observability_version:
# description: "The version for observability image. Only present for rollback functionality"
# required: false
# type: string
env:
PACKER_VERSION: "latest"
AWS_ROLE_ARN: "arn:aws:iam::192549843005:role/github-devops-cd"
IMAGE_COUNT_UPPER_LIMIT: 20
IMAGE_COUNT_LOWER_LIMIT: 10
# CONCORDIUM_NODE_VERSION: ${{ inputs.node_version }}
CONCORDIUM_NODE_VERSION: 7.0.6-5
# RELEASE_TYPE: ${{ inputs.release_type }}
RELEASE_TYPE: rc
permissions:
id-token: write
contents: read
jobs:
generate-matrix:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Initialize Matrix with alpha environments
run: |
MATRIX_JSON=$(echo '[
{
"env": "stagenet",
"tld": "com",
"cloud_provider": "aws"
},
{
"env": "flynet",
"tld": "com",
"cloud_provider": "aws"
},
{
"env": "stagenet",
"tld": "com",
"cloud_provider": "gcp"
}
]' | jq -c)
echo "MATRIX_JSON=${MATRIX_JSON}" >> $GITHUB_ENV
- name: Release candidate environments
if: ${{ env.RELEASE_TYPE == 'rc' }}
run: |
MATRIX_JSON=$(echo "$MATRIX_JSON" | jq -c '. + [
{
"env": "testnet",
"tld": "com",
"cloud_provider": "aws"
},
{
"env": "testnet",
"tld": "com",
"cloud_provider": "gcp"
},
{
"env": "mainnet",
"tld": "software",
"cloud_provider": "aws",
"ami_users": '["727113945353"]'
},
{
"env": "mainnet",
"tld": "software",
"cloud_provider": "gcp"
},
]')
echo "MATRIX_JSON=${MATRIX_JSON}" >> $GITHUB_ENV
- name: Output Matrix JSON
id: set-matrix
run: echo "matrix=$MATRIX_JSON" >> $GITHUB_OUTPUT
release-concordium-node-image:
outputs:
image_name_gcp_stagenet: ${{ steps.image_name.outputs.image_name_gcp_stagenet }}
# image_name_gcp_testnet: ${{ steps.image_name.outputs.image_name_gcp_testnet }}
# image_name_gcp_mainnet: ${{ steps.image_name.outputs.image_name_gcp_mainnet }}
image_name_aws_stagenet: ${{ steps.image_name.outputs.image_name_aws_stagenet }}
# image_name_aws_testnet: ${{ steps.image_name.outputs.image_name_aws_testnet }}
# image_name_aws_mainnet: ${{ steps.image_name.outputs.image_name_aws_mainnet }}
image_name_aws_flynet: ${{ steps.image_name.outputs.image_name_aws_flynet }}
needs: [generate-matrix]
environment: release-node-images
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.generate-matrix.outputs.matrix) }}
defaults:
run:
working-directory: ./packer
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Load common variables
run: cat ../.github/shared-variables/.env >> $GITHUB_ENV
- name: Configure GCP credentials
uses: google-github-actions/auth@v2
with:
project_id: concordium-mgmt-0
workload_identity_provider: projects/761241104197/locations/global/workloadIdentityPools/github/providers/concordium
service_account: [email protected]
- name: Setup AWS REGION
run: |
VALUE=$(echo '${{ env.ENVIRONMENT_TO_AWS_REGION }}' | jq -r --arg key "${{ matrix.env }}" '.[$key]')
if [[ $VALUE == "null" || $VALUE == "" ]]; then
echo "Key '${{ matrix.env }}' not found in ${{ env.ENVIRONMENT_TO_AWS_REGION }}"
exit 1
fi
echo "AWS_ENVIRONMENT_REGION=$VALUE" >> $GITHUB_ENV
- name: Setup subnet id
if: ${{ matrix.cloud_provider == 'aws' }}
run: |
VALUE=$(echo '${{ env.REGION_TO_SUBNET }}' | jq -r --arg key "${{ env.AWS_ENVIRONMENT_REGION }}" '.[$key]')
if [[ $VALUE == "null" || $VALUE == "" ]]; then
echo "Key '${{ env.AWS_ENVIRONMENT_REGION }}' not found in ${{ env.REGION_TO_SUBNET }}"
exit 1
fi
echo "SUBNET_ID=$VALUE" >> $GITHUB_ENV
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ${{ env.AWS_ENVIRONMENT_REGION }}
role-to-assume: ${{ env.AWS_ROLE_ARN }}
role-session-name: ReleaseConcordiumNodeImageSession
- name: Download file from S3
run: |
aws s3 cp s3://distribution.${{ matrix.env }}.concordium.${{ matrix.tld }}/deb/concordium-${{ matrix.env }}-node_${{ env.CONCORDIUM_NODE_VERSION }}_amd64.deb ./concordium-node.deb
- name: Setup image name
run: |
if [ "${{ matrix.cloud_provider }}" == "aws" ]; then
echo "IMAGE_NAME=${{ matrix.env }}-${{ env.CONCORDIUM_NODE_VERSION }}-concordium-node-${{ env.OBSERVABILITY_VERSION }}-x86_64" >> $GITHUB_ENV
elif [ "${{ matrix.cloud_provider }}" == "gcp" ]; then
VERSION_TRANSFORMED=${CONCORDIUM_NODE_VERSION//./-}
echo "IMAGE_NAME=${{ matrix.env }}-v$VERSION_TRANSFORMED-concordium-node-${{ env.OBSERVABILITY_VERSION }}-x86-64" >> $GITHUB_ENV
else
echo "Unknown cloud provider: ${{ matrix.cloud_provider }}"
exit 1
fi
- name: Test if image exists
run: |
if [ "${{ matrix.cloud_provider }}" == "aws" ]; then
echo "IMAGE_ID=$(aws ec2 describe-images --filters Name=name,Values=$IMAGE_NAME --query 'Images[*].ImageId' --output text)" >> $GITHUB_ENV
elif [ "${{ matrix.cloud_provider }}" == "gcp" ]; then
echo "IMAGE_ID=$(gcloud compute images list --project="concordium-${{ matrix.env }}-0" --filter="name=($IMAGE_NAME)" --format="value(name)")" >> $GITHUB_ENV
else
echo "Unknown cloud provider: ${{ matrix.cloud_provider }}"
exit 1
fi
- name: Set source image id
if: ${{ env.IMAGE_ID == '' }}
run: |
if [ "${{ matrix.cloud_provider }}" == "aws" ]; then
SOURCE_IMAGE_ID=$(aws ec2 describe-images --filters Name=name,Values=concordium-observability-node-${{ env.OBSERVABILITY_VERSION }}-x86_64 --query 'Images[*].ImageId' --output text)
elif [ "${{ matrix.cloud_provider }}" == "gcp" ]; then
SOURCE_IMAGE_ID=$(gcloud compute images list --project="concordium-mgmt-0" --filter="name=(concordium-observability-node-${{ env.OBSERVABILITY_VERSION }}-x86-64)" --format="value(name)")
else
echo "Unknown cloud provider: ${{ matrix.cloud_provider }}"
exit 1
fi
echo "SOURCE_IMAGE_ID=$SOURCE_IMAGE_ID" >> $GITHUB_ENV
- name: Packer concordium-node init
if: ${{ env.IMAGE_ID == '' }}
run: packer init concordium-node
- name: Set variables
if: ${{ env.IMAGE_ID == '' }}
run: |
export CLOUD_PROVIDER=${{ matrix.cloud_provider }}
export ENVIRONMENT=${{ matrix.env }}
export CONCORDIUM_NODE_PATH=./concordium-node.deb
export AWS_SUBNET_ID=${{ env.SUBNET_ID }}
export AMI_USERS='${{ matrix.ami_users }}'
if [ "$AMI_USERS" == "" ]; then
export AMI_USERS='[]'
fi
envsubst < concordium-node/variables.pkrvars.hcl.template > variables.pkrvars.hcl
- name: Build concordium-node image
if: ${{ env.IMAGE_ID == '' }}
run: packer build -var-file=./variables.pkrvars.hcl concordium-node
- name: Output image name
if: ${{ env.IMAGE_ID == '' }}
id: image_name
run: |
echo "image_name_${{ matrix.cloud_provider }}_${{ matrix.env }}=$IMAGE_NAME" >> $GITHUB_OUTPUT
# notify-slack-changes:
# needs: [release-observability-image, release-concordium-node-image]
# environment: release-images
# runs-on: ubuntu-latest
# if: ${{ always() }}
# steps:
# - name: Sample updated Image IDs
# run: |
# echo '${{ toJson(needs.release-concordium-node-image.outputs) }}' > info.json
# UPDATED_IMAGE_IDS=$(cat info.json | jq -c \
# --arg el1 $(echo '${{ toJson(needs.release-observability-image.outputs) }}' | jq -r .image_name_gcp) \
# --arg el2 $(echo '${{ toJson(needs.release-observability-image.outputs) }}' | jq -r .image_name_aws) \
# '. + (if $el1 != "" and ($el1 != "null") then {"image_name_gcp_observability": $el1 } else {} end) + (if $el2 != "" and ($el2 != "null") then {"image_name_aws_observability": $el2 } else {} end)' | jq -R | sed 's/^"//;s/"$//')
# echo "UPDATED_IMAGE_IDS=$UPDATED_IMAGE_IDS" >> $GITHUB_ENV
# - name: Send updated image ids to slack
# if: ${{ env.UPDATED_IMAGE_IDS != '{}' && env.UPDATED_IMAGE_IDS != '' }}
# uses: slackapi/[email protected]
# with:
# payload: >-
# {
# "text": "The following image ids has been updated: ${{ env.UPDATED_IMAGE_IDS }}"
# }
# env:
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_URL }}
#
# fetch-images:
# needs: [release-concordium-node-image]
# runs-on: ubuntu-latest
# environment: release-images
# outputs:
# images: ${{ steps.fetch-images.outputs.images }}
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
#
# - name: Configure GCP credentials
# uses: google-github-actions/auth@v2
# with:
# project_id: concordium-mgmt-0
# workload_identity_provider: projects/761241104197/locations/global/workloadIdentityPools/github/providers/concordium
# service_account: [email protected]
#
# - name: Configure AWS Credentials
# uses: aws-actions/configure-aws-credentials@v4
# with:
# aws-region: ${{ env.OBSERVABILITY_AWS_REGION }}
# role-to-assume: ${{ env.AWS_ROLE_ARN }}
# role-session-name: ReleaseConcordiumNodeImageSession
#
# - name: Set up Python
# uses: actions/setup-python@v5
# with:
# python-version: '3.11'
#
# - name: Fetch images to be deleted
# id: fetch-images
# run: |
# set -e
# TARGET_AWS_REGIONS=$(echo '${{ env.ENVIRONMENT_TO_AWS_REGION }}' | jq -r -c '[..|strings]|unique| join(" ")')
# IMAGES=$(python tools/find_images.py --image_count_lower_limit ${{ env.IMAGE_COUNT_LOWER_LIMIT }} --image_count_upper_limit ${{ env.IMAGE_COUNT_UPPER_LIMIT }} --aws_regions $TARGET_AWS_REGIONS)
# echo "images=$(echo $IMAGES | jq '@json' | sed 's/^"\(.*\)"$/\1/')" >> $GITHUB_OUTPUT
#
# notify-slack-on-image-deletions:
# needs: [fetch-images]
# environment: release-images
# runs-on: ubuntu-latest
# if: ${{ needs.fetch-images.outputs.images != '{}' }}
# steps:
# - name: Send GitHub Action trigger data to Slack workflow
# uses: slackapi/[email protected]
# with:
# payload: >-
# {
# "text": "There are image which should be deleted: ```$DEVOPS_REPOSITORY_PATH/tools/delete_amis.sh '${{ needs.fetch-images.outputs.images }}'```"
# }
# env:
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_URL }}
#
# notify-slack-on-failure:
# needs: [release-observability-image, release-concordium-node-image]
# environment: release-images
# runs-on: ubuntu-latest
# if: ${{ failure() }}
# steps:
# - name: Send GitHub Action trigger data to Slack workflow
# uses: slackapi/[email protected]
# with:
# payload: >-
# {
# "text": "One or more GitHub Actions jobs failed: <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Click here> to see the run."
# }
# env:
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_URL }}