Build Cloud and Vagrant Images #180
This file contains hidden or 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
| name: Build Cloud and Vagrant Images | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| date_time_stamp: | |
| description: 'Custom date+time stamp, YYYYMMDDhhmmss' | |
| required: false | |
| default: '' | |
| version_major: | |
| description: 'AlmaLinux major version' | |
| required: true | |
| default: '10' | |
| type: choice | |
| options: | |
| - 10-kitten | |
| - 10 | |
| - 9 | |
| - 8 | |
| image_type: | |
| description: 'Cloud image type' | |
| required: true | |
| default: 'NONE' | |
| type: choice | |
| options: | |
| - NONE | |
| - ALL | |
| - azure | |
| # - digitalocean # TODO: require data to work with the cloud, such as: bucket, access key, secret key, etc. | |
| - gcp | |
| - gencloud | |
| - oci | |
| - opennebula | |
| vagrant_type: | |
| description: 'Vagrant image type' | |
| required: true | |
| default: 'NONE' | |
| type: choice | |
| options: | |
| - NONE | |
| - ALL | |
| - vagrant_libvirt | |
| - vagrant_virtualbox | |
| - vagrant_vmware | |
| self-hosted: | |
| description: "Allow self-hosted runner (aarch64 or vagrant_vmware only)" | |
| required: true | |
| type: boolean | |
| default: true | |
| self_hosted_runner: | |
| description: 'self-hosted runner' | |
| required: true | |
| default: 'aws-ec2' | |
| type: choice | |
| options: | |
| - self-hosted | |
| - aws-ec2 | |
| run_test: | |
| description: "Do image simple testing and generate installed packages list (vagrant_* only)" | |
| required: true | |
| type: boolean | |
| default: true | |
| store_as_artifact: | |
| description: "Store images to the workflow Artifacts" | |
| required: true | |
| type: boolean | |
| default: false | |
| upload_to_s3: | |
| description: "Upload to S3 Bucket" | |
| required: true | |
| type: boolean | |
| default: true | |
| notify_mattermost: | |
| description: "Send notification to Mattermost" | |
| required: true | |
| type: boolean | |
| default: false | |
| env: | |
| PACKER_GITHUB_API_TOKEN: ${{ secrets.GIT_HUB_TOKEN }} | |
| jobs: | |
| init-data: | |
| name: Initialize common data | |
| runs-on: ubuntu-24.04 | |
| outputs: | |
| time_stamp: ${{ steps.date-time-stamp.outputs.time_stamp }} | |
| date_stamp: ${{ steps.date-time-stamp.outputs.date_stamp }} | |
| matrix_gh: ${{ steps.set-matrix.outputs.matrix_gh }} | |
| matrix_sh: ${{ steps.set-matrix.outputs.matrix_sh }} | |
| steps: | |
| - name: Set matrix | |
| id: set-matrix | |
| run: | | |
| # Build matrix is json array of string elements like: | |
| matrix_gh= # ["azure-x86_64", "gencloud-x86_64", ...] | |
| matrix_sh= # ["azure-aarch64", "gencloud-aarch64", ... , "vagrant_vmware-x86_64"] | |
| # Cloud Images | |
| if [ "${{ inputs.image_type }}" = "azure" -o "${{ inputs.image_type }}" = "ALL" ]; then | |
| VARIANTS_GH+=("azure-x86_64") | |
| VARIANTS_SH+=("azure-aarch64") | |
| fi | |
| if [ "${{ inputs.image_type }}" = "gcp" -o "${{ inputs.image_type }}" = "ALL" ]; then | |
| VARIANTS_GH+=("gcp-x86_64") | |
| VARIANTS_SH+=("gcp-aarch64") | |
| fi | |
| # TODO: require data to work with the cloud, such as: bucket, access key, secret key, etc. | |
| # if [ "${{ inputs.image_type }}" = "digitalocean" -o "${{ inputs.image_type }}" = "ALL" ]; then | |
| # if [[ "${{ inputs.version_major }}" != *"kitten"* ]] && [[ "${{ inputs.version_major }}" != *"10" ]]; then | |
| # VARIANTS_GH+=("digitalocean-x86_64") | |
| # fi | |
| # fi | |
| if [ "${{ inputs.image_type }}" = "gencloud" -o "${{ inputs.image_type }}" = "ALL" ]; then | |
| VARIANTS_GH+=("gencloud-x86_64") | |
| VARIANTS_SH+=("gencloud-aarch64") | |
| fi | |
| if [ "${{ inputs.image_type }}" = "oci" -o "${{ inputs.image_type }}" = "ALL" ]; then | |
| if [[ "${{ inputs.version_major }}" != *"kitten"* ]]; then | |
| VARIANTS_GH+=("oci-x86_64") | |
| VARIANTS_SH+=("oci-aarch64") | |
| fi | |
| fi | |
| if [ "${{ inputs.image_type }}" = "opennebula" -o "${{ inputs.image_type }}" = "ALL" ]; then | |
| VARIANTS_GH+=("opennebula-x86_64") | |
| VARIANTS_SH+=("opennebula-aarch64") | |
| fi | |
| # Vagrant Images | |
| if [ "${{ inputs.vagrant_type }}" = "vagrant_libvirt" -o "${{ inputs.vagrant_type }}" = "ALL" ]; then | |
| VARIANTS_GH+=("vagrant_libvirt-x86_64") | |
| fi | |
| if [ "${{ inputs.vagrant_type }}" = "vagrant_virtualbox" -o "${{ inputs.vagrant_type }}" = "ALL" ]; then | |
| VARIANTS_GH+=("vagrant_virtualbox-x86_64") # tests aren't work on GitHub runners, use self-hosted to run tests | |
| fi | |
| if [ "${{ inputs.vagrant_type }}" = "vagrant_vmware" -o "${{ inputs.vagrant_type }}" = "ALL" ]; then | |
| VARIANTS_SH+=("vagrant_vmware-x86_64") # VMware has networking issues on GitHub runners, so we use self-hosted runner | |
| fi | |
| [ ${#VARIANTS_GH[@]} -ne 0 ] && matrix_gh=$(printf '"%s",' "${VARIANTS_GH[@]}") | |
| matrix_gh=${matrix_gh%,} # Remove the trailing comma | |
| echo matrix_gh=$(jq -c <<< [${matrix_gh}]) >> $GITHUB_OUTPUT | |
| echo "[Debug] on GitHub Hosted [${matrix_gh}]" | |
| [ ${#VARIANTS_SH[@]} -ne 0 ] && matrix_sh=$(printf '"%s",' "${VARIANTS_SH[@]}") | |
| matrix_sh=${matrix_sh%,} # Remove the trailing comma | |
| echo matrix_sh=$(jq -c <<< [${matrix_sh}]) >> $GITHUB_OUTPUT | |
| echo "[Debug] on Self Hosted [${matrix_sh}]" | |
| - name: Date+time stamp | |
| id: date-time-stamp | |
| run: | | |
| # date+time stamp, YYYYMMDDhhmmss | |
| if [ "${{ inputs.date_time_stamp }}" != "" ]; then | |
| date_time_stamp="${{ inputs.date_time_stamp }}" | |
| else | |
| date_time_stamp=$(date -u '+%Y%m%d%H%M%S') | |
| fi | |
| echo "time_stamp=${date_time_stamp}" >> $GITHUB_OUTPUT | |
| # date stamp, YYYYMMDD | |
| date_stamp=${date_time_stamp:0:-6} | |
| echo "date_stamp=${date_stamp}" >> "$GITHUB_OUTPUT" | |
| build-gh-hosted: | |
| name: ${{ matrix.variant }} ${{ matrix.matrix_gh }} image | |
| permissions: | |
| id-token: write | |
| contents: read | |
| needs: [init-data] | |
| if: ${{ needs.init-data.outputs.matrix_gh != '[]' }} | |
| # use runs-on runners if within the almalinux org, otherwise GH runners" | |
| runs-on: >- | |
| ${{ | |
| github.repository_owner == 'AlmaLinux' && | |
| format('runs-on={0}/family=c7i.metal-24xl+c7a.metal-48xl+*8gd.metal*/image=ubuntu24-full-x64', github.run_id) | |
| || | |
| 'ubuntu-24.04' | |
| }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: ${{ fromJSON(format('["{0}"]', ( inputs.version_major == '10-kitten' || inputs.version_major == '10' ) && format('{0}", "{0}-v2', inputs.version_major) || inputs.version_major )) }} | |
| matrix_gh: ${{ fromJSON(needs.init-data.outputs.matrix_gh) }} | |
| exclude: | |
| - matrix_gh: 'azure-x86_64' | |
| variant: '10-kitten-v2' | |
| - matrix_gh: 'oci-x86_64' | |
| variant: '10-kitten-v2' | |
| - matrix_gh: 'gcp-x86_64' | |
| variant: '10-kitten-v2' | |
| - matrix_gh: 'digitalocean-x86_64' | |
| variant: '10-kitten-v2' | |
| - matrix_gh: 'azure-x86_64' | |
| variant: '10-v2' | |
| - matrix_gh: 'gcp-x86_64' | |
| variant: '10-v2' | |
| - matrix_gh: 'oci-x86_64' | |
| variant: '10-v2' | |
| - matrix_gh: 'digitalocean-x86_64' | |
| variant: '10-v2' | |
| env: | |
| TIME_STAMP: ${{ needs.init-data.outputs.time_stamp }} | |
| DATE_STAMP: ${{ needs.init-data.outputs.date_stamp }} | |
| steps: | |
| - name: Prepare some environment variables | |
| run: | | |
| # Read image type | |
| IFS=- read -r type arch <<< "${{ matrix.matrix_gh }}" | |
| echo "type=$type" >> $GITHUB_ENV | |
| echo "ARCH=$arch" >> $GITHUB_ENV | |
| - name: Checkout ${{ github.action_repository }} | |
| uses: actions/checkout@v5 | |
| - uses: ./.github/actions/shared-steps | |
| name: ${{ matrix.variant }} ${{ matrix.matrix_gh }} image | |
| with: | |
| type: ${{ env.type }} | |
| variant: ${{ matrix.variant }} | |
| arch: ${{ env.ARCH }} | |
| S3_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| AWS_REGION: ${{ vars.AWS_REGION }} | |
| AWS_S3_BUCKET: ${{ vars.AWS_S3_BUCKET }} | |
| MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }} | |
| MATTERMOST_CHANNEL: ${{ vars.MATTERMOST_CHANNEL }} | |
| store_as_artifact: ${{ inputs.store_as_artifact }} | |
| upload_to_s3: ${{ inputs.upload_to_s3 }} | |
| notify_mattermost: ${{ inputs.notify_mattermost }} | |
| run_test: ${{ contains(env.type, 'vagrant') && inputs.run_test && 'true' || 'false' }} # Do image simple testing and generate installed packages list (vagrant_* only) | |
| runner: ${{ github.repository_owner == 'AlmaLinux' && 'aws-ec2' || 'gh_hosted' }} | |
| env: | |
| PACKER_GITHUB_API_TOKEN: ${{ secrets.GIT_HUB_TOKEN }} | |
| # The job is to start self-hosted runner on AWS EC2 instance if not in the almalinux org | |
| # It does nothing if in the almalinux org, so 'Setup and start runner' step is skipped | |
| start-self-hosted-runner: | |
| name: ${{ matrix.variant }} ${{ matrix.matrix_sh }} runner | |
| if: ${{ inputs.self-hosted && needs.init-data.outputs.matrix_sh != '[]' }} | |
| runs-on: ubuntu-24.04 | |
| needs: [init-data] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: ${{ fromJSON(format('["{0}"]', ( (contains(needs.init-data.outputs.matrix_sh, 'azure-aarch64') && ( inputs.version_major == '9' || inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-64k', inputs.version_major) || ( ( (inputs.vagrant_type == 'vagrant_vmware' || inputs.vagrant_type == 'ALL') && ( inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-v2', inputs.version_major) || inputs.version_major ) ) )) }} | |
| matrix_sh: ${{ fromJSON(needs.init-data.outputs.matrix_sh) }} | |
| exclude: | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '10-kitten' | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '9-64k' | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '10-kitten-64k' | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '10-64k' | |
| - matrix_sh: 'gencloud-aarch64' | |
| variant: '9-64k' | |
| - matrix_sh: 'gencloud-aarch64' | |
| variant: '10-kitten-64k' | |
| - matrix_sh: 'gencloud-aarch64' | |
| variant: '10-64k' | |
| - matrix_sh: 'opennebula-aarch64' | |
| variant: '9-64k' | |
| - matrix_sh: 'opennebula-aarch64' | |
| variant: '10-kitten-64k' | |
| - matrix_sh: 'opennebula-aarch64' | |
| variant: '10-64k' | |
| steps: | |
| - name: Setup and start runner | |
| if: inputs.self_hosted_runner == 'aws-ec2' && github.repository_owner != 'AlmaLinux' | |
| uses: NextChapterSoftware/ec2-action-builder@v1.10 | |
| with: | |
| github_token: ${{ secrets.GIT_HUB_TOKEN }} | |
| aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| aws_region: ${{ vars.AWS_REGION }} | |
| ec2_ami_id: ${{ secrets[format('EC2_AMI_ID_AL9_{0}', ( contains(matrix.matrix_sh, 'x86_64') && 'X86_64' || 'AARCH64' ))] }} | |
| ec2_subnet_id: ${{ secrets.EC2_SUBNET_ID}} # Subnet and Security Group should match | |
| ec2_security_group_id: ${{ secrets.EC2_SECURITY_GROUP_ID }} # Availability Zones list for 'a1.metal' Instance Type | |
| ec2_instance_type: ${{ contains(matrix.matrix_sh, 'x86_64') && 'c5n.metal' || 'a1.metal' }} | |
| # aarch64 - t4g.medium a1.metal | |
| # x86_64 - t3.medium c5n.metal | |
| ec2_root_disk_size_gb: "16" # override default size which is too small for actions and tests stuff | |
| ec2_root_disk_ebs_class: "gp3" # use faster and cheeper storage instead of default 'gp2' | |
| ec2_instance_ttl: 30 # Optional (default is 60 minutes) | |
| ec2_spot_instance_strategy: None # Other options are: SpotOnly, BestEffort, MaxPerformance | |
| ec2_instance_tags: > # Required for IAM role resource permission scoping | |
| [ | |
| {"Key": "Project", "Value": "GitHub Actions Self-hosted Runners"} | |
| ] | |
| build-self-hosted: | |
| name: ${{ matrix.variant }} ${{ matrix.matrix_sh }} image | |
| permissions: | |
| id-token: write | |
| contents: read | |
| if: ${{ inputs.self-hosted && needs.init-data.outputs.matrix_sh != '[]' }} | |
| needs: [init-data, start-self-hosted-runner] | |
| # If almalinux org, use RunsOn with: | |
| # - AlmaLinux 9.x x86_64 specific AWS AMI ID (need to build Vagrant for VMware) | |
| # - ubuntu24-full-arm64 for GCP on aarch64 | |
| # | |
| # Otherwise use AWS EC2 Self-Hosted x86_64 or aarch64 runner set up with the 'start-self-hosted-runner' job above | |
| # | |
| # Or use manually set up runner. Vagrant for VirtualBox x86_64 runner configuration example: | |
| # ./config.sh --url https://github.com/almalinux/cloud-images --token ***** --name vagrant_virtualbox-x86_64 --labels vagrant_virtualbox-x86_64 --no-default-labels --work _work --runnergroup default --replace | |
| runs-on: >- | |
| ${{ | |
| github.repository_owner == 'AlmaLinux' && ( | |
| contains(matrix.matrix_sh, 'x86_64') && | |
| format('runs-on={0}/family=c5n.metal/ami={1}', github.run_id, vars.EC2_AMI_ID_AL9_X86_64) | |
| || | |
| contains(matrix.matrix_sh, 'gcp') && | |
| format('runs-on={0}/family=c7i.metal-24xl+c7a.metal-48xl+*8gd.metal*/image=ubuntu24-full-arm64', github.run_id) | |
| || | |
| format('runs-on={0}/family=a1.metal/image=almalinux-9-aarch64', github.run_id) | |
| ) | |
| || | |
| inputs.self_hosted_runner == 'aws-ec2' && github.run_id | |
| || | |
| matrix.matrix_sh | |
| }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| variant: ${{ fromJSON(format('["{0}"]', ( (contains(needs.init-data.outputs.matrix_sh, 'azure-aarch64') && ( inputs.version_major == '9' || inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-64k', inputs.version_major) || ( ( (inputs.vagrant_type == 'vagrant_vmware' || inputs.vagrant_type == 'ALL') && ( inputs.version_major == '10' || inputs.version_major == '10-kitten' ) ) && format('{0}", "{0}-v2', inputs.version_major) || inputs.version_major ) ) )) }} | |
| matrix_sh: ${{ fromJSON(needs.init-data.outputs.matrix_sh) }} | |
| exclude: | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '10-kitten' | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '10' | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '9-64k' | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '10-kitten-64k' | |
| - matrix_sh: 'oci-aarch64' | |
| variant: '10-64k' | |
| - matrix_sh: 'gencloud-aarch64' | |
| variant: '9-64k' | |
| - matrix_sh: 'gencloud-aarch64' | |
| variant: '10-kitten-64k' | |
| - matrix_sh: 'gencloud-aarch64' | |
| variant: '10-64k' | |
| - matrix_sh: 'opennebula-aarch64' | |
| variant: '9-64k' | |
| - matrix_sh: 'opennebula-aarch64' | |
| variant: '10-kitten-64k' | |
| - matrix_sh: 'opennebula-aarch64' | |
| variant: '10-64k' | |
| env: | |
| TIME_STAMP: ${{ needs.init-data.outputs.time_stamp }} | |
| DATE_STAMP: ${{ needs.init-data.outputs.date_stamp }} | |
| steps: | |
| - name: Prepare some environment variables | |
| run: | | |
| # Read image type | |
| IFS=- read -r type arch <<< "${{ matrix.matrix_sh }}" | |
| echo "type=$type" >> $GITHUB_ENV | |
| echo "ARCH=$arch" >> $GITHUB_ENV | |
| - name: Clean up runner | |
| if: inputs.self_hosted_runner != 'aws-ec2' | |
| run: sudo rm -rf ansible .vagrant output-* | |
| - name: Checkout ${{ github.action_repository }} | |
| uses: actions/checkout@v4 | |
| - uses: ./.github/actions/shared-steps | |
| name: ${{ matrix.variant }} ${{ matrix.matrix_sh }} image | |
| with: | |
| type: ${{ env.type }} | |
| variant: ${{ matrix.variant }} | |
| arch: ${{ env.ARCH }} | |
| S3_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
| S3_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
| AWS_REGION: ${{ vars.AWS_REGION }} | |
| AWS_S3_BUCKET: ${{ vars.AWS_S3_BUCKET }} | |
| MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK_URL }} | |
| MATTERMOST_CHANNEL: ${{ vars.MATTERMOST_CHANNEL }} | |
| store_as_artifact: ${{ inputs.store_as_artifact }} | |
| upload_to_s3: ${{ inputs.upload_to_s3 }} | |
| notify_mattermost: ${{ inputs.notify_mattermost }} | |
| run_test: ${{ contains(env.type, 'vagrant') && inputs.run_test && 'true' || 'false' }} # Do image simple testing and generate installed packages list (vagrant_* only) | |
| runner: ${{ github.repository_owner == 'AlmaLinux' && 'aws-ec2' || 'self_hosted' }} | |
| env: | |
| PACKER_GITHUB_API_TOKEN: ${{ secrets.GIT_HUB_TOKEN }} |