|
| 1 | +name: 'Release DLC Image (Three Steps)' |
| 2 | +description: 'Complete DLC release workflow: publish images, generate release info, and publish notifications' |
| 3 | + |
| 4 | +inputs: |
| 5 | + source-image-uri: |
| 6 | + description: 'Full ECR image URI to pull and promote (e.g., 123456789012.dkr.ecr.us-west-2.amazonaws.com/repo:tag)' |
| 7 | + required: true |
| 8 | + release-spec-content: |
| 9 | + description: 'YAML content for release specification' |
| 10 | + required: true |
| 11 | + release-package-s3-bucket: |
| 12 | + description: 'S3 bucket containing the release package' |
| 13 | + required: false |
| 14 | + default: 'dlc-release-logic-v2' |
| 15 | + release-package-s3-prefix: |
| 16 | + description: 'S3 prefix/folder path to the package' |
| 17 | + required: false |
| 18 | + default: 'DLContainersReleaseLogicV2/DLContainersReleaseLogicV2' |
| 19 | + aws-region: |
| 20 | + description: 'AWS region for S3 and ECR' |
| 21 | + required: false |
| 22 | + default: 'us-west-2' |
| 23 | + source-stage: |
| 24 | + description: 'Source stage (e.g., private, beta)' |
| 25 | + required: true |
| 26 | + target-stage: |
| 27 | + description: 'Target stage (e.g., gamma, release)' |
| 28 | + required: true |
| 29 | + python-version: |
| 30 | + description: 'Python version to use' |
| 31 | + required: false |
| 32 | + default: '3.12' |
| 33 | + arch: |
| 34 | + description: 'Architecture (amd64 or arm64)' |
| 35 | + required: false |
| 36 | + default: 'amd64' |
| 37 | + |
| 38 | +outputs: |
| 39 | + release-metadata-file: |
| 40 | + description: 'Path to release metadata file' |
| 41 | + value: '/tmp/release_metadata.dict' |
| 42 | + release-completed: |
| 43 | + description: 'Whether all three steps completed successfully' |
| 44 | + value: ${{ steps.step3.outputs.success }} |
| 45 | + |
| 46 | +runs: |
| 47 | + using: 'composite' |
| 48 | + steps: |
| 49 | + - name: Setup Python |
| 50 | + uses: actions/setup-python@v5 |
| 51 | + with: |
| 52 | + python-version: ${{ inputs.python-version }} |
| 53 | + |
| 54 | + - name: Install SOCI and nerdctl |
| 55 | + shell: bash |
| 56 | + run: | |
| 57 | + echo "Installing SOCI and nerdctl..." |
| 58 | + ARCH_SUFFIX="${{ inputs.arch }}" |
| 59 | + echo "Using architecture: ${ARCH_SUFFIX}" |
| 60 | +
|
| 61 | + # **************** SOCI SNAPSHOTTER ********************************************* |
| 62 | + echo "Installing SOCI for ${ARCH_SUFFIX}..." |
| 63 | + SOCI_VERSION="0.11.1" |
| 64 | + wget https://github.com/awslabs/soci-snapshotter/releases/download/v${SOCI_VERSION}/soci-snapshotter-${SOCI_VERSION}-linux-${ARCH_SUFFIX}.tar.gz |
| 65 | + sudo tar -C /usr/local/bin -xvf soci-snapshotter-${SOCI_VERSION}-linux-${ARCH_SUFFIX}.tar.gz soci soci-snapshotter-grpc |
| 66 | + rm soci-snapshotter-${SOCI_VERSION}-linux-${ARCH_SUFFIX}.tar.gz |
| 67 | + soci --version |
| 68 | + echo "Successfully installed SOCI v${SOCI_VERSION} for ${ARCH_SUFFIX}" |
| 69 | + # **************** END SOCI SNAPSHOTTER ***************************************** |
| 70 | +
|
| 71 | + # **************** NERDCTL ****************************************************** |
| 72 | + echo "Installing nerdctl for ${ARCH_SUFFIX}..." |
| 73 | + export CONTAINERD_ADDRESS=/var/run/docker/containerd/containerd.sock |
| 74 | + NERDCTL_VERSION="2.1.5" |
| 75 | + wget https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-${ARCH_SUFFIX}.tar.gz |
| 76 | + sudo tar -C /usr/local/bin -xzf nerdctl-${NERDCTL_VERSION}-linux-${ARCH_SUFFIX}.tar.gz |
| 77 | + sudo chmod +x /usr/local/bin/nerdctl |
| 78 | + rm nerdctl-${NERDCTL_VERSION}-linux-${ARCH_SUFFIX}.tar.gz |
| 79 | + nerdctl --version |
| 80 | + echo "Successfully installed nerdctl v${NERDCTL_VERSION} for ${ARCH_SUFFIX}" |
| 81 | + # **************** END NERDCTL ************************************************** |
| 82 | +
|
| 83 | + echo "CONTAINERD_ADDRESS=/var/run/docker/containerd/containerd.sock" >> ${GITHUB_ENV} |
| 84 | + echo "ARCH=${ARCH_SUFFIX}" >> ${GITHUB_ENV} |
| 85 | +
|
| 86 | + - name: Download and install release package |
| 87 | + shell: bash |
| 88 | + run: | |
| 89 | + echo "Downloading release package from S3..." |
| 90 | + PACKAGE_DIR="release_package" |
| 91 | + mkdir -p ${PACKAGE_DIR} |
| 92 | +
|
| 93 | + aws s3 sync \ |
| 94 | + s3://${{ inputs.release-package-s3-bucket }}/${{ inputs.release-package-s3-prefix }} \ |
| 95 | + ${PACKAGE_DIR} \ |
| 96 | + --region ${{ inputs.aws-region }} |
| 97 | +
|
| 98 | + if [ ! -d "${PACKAGE_DIR}" ] || [ -z "$(ls -A ${PACKAGE_DIR})" ]; then |
| 99 | + echo "Error: Failed to download package from S3" |
| 100 | + exit 1 |
| 101 | + fi |
| 102 | +
|
| 103 | + echo "Installing release package..." |
| 104 | + python -m pip install --upgrade pip |
| 105 | + pip install -e ./${PACKAGE_DIR} |
| 106 | +
|
| 107 | + echo "PACKAGE_DIR=${PACKAGE_DIR}" >> ${GITHUB_ENV} |
| 108 | +
|
| 109 | + - name: Set release environment variables |
| 110 | + shell: bash |
| 111 | + run: | |
| 112 | + echo "Setting release environment variables..." |
| 113 | + echo "REGION=${{ inputs.aws-region }}" >> ${GITHUB_ENV} |
| 114 | + echo "SOURCE_STAGE=${{ inputs.source-stage }}" >> ${GITHUB_ENV} |
| 115 | + echo "TARGET_STAGE=${{ inputs.target-stage }}" >> ${GITHUB_ENV} |
| 116 | +
|
| 117 | + echo "Environment variables set:" |
| 118 | + echo " REGION: ${{ inputs.aws-region }}" |
| 119 | + echo " SOURCE_STAGE: ${{ inputs.source-stage }}" |
| 120 | + echo " TARGET_STAGE: ${{ inputs.target-stage }}" |
| 121 | +
|
| 122 | + - name: Step 1 - Publish DLC Images |
| 123 | + id: step1 |
| 124 | + shell: bash |
| 125 | + run: | |
| 126 | + echo "==========================================" |
| 127 | + echo "Step 1: Publishing DLC Images" |
| 128 | + echo "==========================================" |
| 129 | + echo "Region: ${REGION}" |
| 130 | + echo "Source Stage: ${SOURCE_STAGE}" |
| 131 | + echo "Target Stage: ${TARGET_STAGE}" |
| 132 | + echo "Source Image URI: ${{ inputs.source-image-uri }}" |
| 133 | +
|
| 134 | + # Create release spec file |
| 135 | + cat > release_spec.yml <<'EOF' |
| 136 | + ${{ inputs.release-spec-content }} |
| 137 | + EOF |
| 138 | +
|
| 139 | + echo "Release specification:" |
| 140 | + cat release_spec.yml |
| 141 | +
|
| 142 | + # Run publish_dlc_images with source image URI |
| 143 | + publish_dlc_images --release-spec release_spec.yml --source-image-uri "${{ inputs.source-image-uri }}" |
| 144 | +
|
| 145 | + echo "Step 1 completed: Images published successfully" |
| 146 | +
|
| 147 | + # Verify metadata file was created |
| 148 | + if [ -f "/tmp/release_metadata.dict" ]; then |
| 149 | + echo "Release metadata created:" |
| 150 | + cat /tmp/release_metadata.dict |
| 151 | + echo "success=true" >> ${GITHUB_OUTPUT} |
| 152 | + else |
| 153 | + echo "Error: Release metadata file not found" |
| 154 | + echo "success=false" >> ${GITHUB_OUTPUT} |
| 155 | + exit 1 |
| 156 | + fi |
| 157 | +
|
| 158 | + - name: Step 2 - Generate Release Information |
| 159 | + id: step2 |
| 160 | + if: steps.step1.outputs.success == 'true' |
| 161 | + shell: bash |
| 162 | + run: | |
| 163 | + echo "==========================================" |
| 164 | + echo "Step 2: Generating Release Information" |
| 165 | + echo "==========================================" |
| 166 | + echo "Region: ${REGION}" |
| 167 | + echo "Source Stage: ${SOURCE_STAGE}" |
| 168 | + echo "Target Stage: ${TARGET_STAGE}" |
| 169 | +
|
| 170 | + # Verify metadata from Step 1 exists |
| 171 | + if [ ! -f "/tmp/release_metadata.dict" ]; then |
| 172 | + echo "Error: Release metadata from Step 1 not found" |
| 173 | + echo "Step 1 must complete successfully before Step 2 can run" |
| 174 | + exit 1 |
| 175 | + fi |
| 176 | +
|
| 177 | + echo "Release metadata from Step 1:" |
| 178 | + cat /tmp/release_metadata.dict |
| 179 | +
|
| 180 | + # Run generate_dlc_image_release_information |
| 181 | + generate_dlc_image_release_information |
| 182 | +
|
| 183 | + echo "Step 2 completed: Release information generated and uploaded to S3" |
| 184 | + echo "success=true" >> ${GITHUB_OUTPUT} |
| 185 | +
|
| 186 | + - name: Step 3 - Publish Release Information |
| 187 | + id: step3 |
| 188 | + if: steps.step2.outputs.success == 'true' |
| 189 | + shell: bash |
| 190 | + run: | |
| 191 | + echo "==========================================" |
| 192 | + echo "Step 3: Publishing Release Information" |
| 193 | + echo "==========================================" |
| 194 | + echo "Region: ${REGION}" |
| 195 | + echo "Source Stage: ${SOURCE_STAGE}" |
| 196 | + echo "Target Stage: ${TARGET_STAGE}" |
| 197 | +
|
| 198 | + # Run publish_release_information |
| 199 | + # This script will: |
| 200 | + # 1. Load release info from S3 (uploaded in Step 2) |
| 201 | + # 2. Write image SHA to availability canaries bucket |
| 202 | + # 3. Publish SNS notifications |
| 203 | + publish_release_information |
| 204 | +
|
| 205 | + echo "Step 3 completed: Release information published successfully" |
| 206 | + echo "success=true" >> ${GITHUB_OUTPUT} |
| 207 | +
|
| 208 | + echo "==========================================" |
| 209 | + echo "All three steps completed successfully!" |
| 210 | + echo "==========================================" |
| 211 | +
|
| 212 | + - name: Release Summary |
| 213 | + if: always() |
| 214 | + shell: bash |
| 215 | + run: | |
| 216 | + echo "==========================================" |
| 217 | + echo "Release Execution Summary" |
| 218 | + echo "==========================================" |
| 219 | + echo "Step 1 (Publish Images): ${{ steps.step1.outputs.success || 'failed/skipped' }}" |
| 220 | + echo "Step 2 (Generate Info): ${{ steps.step2.outputs.success || 'failed/skipped' }}" |
| 221 | + echo "Step 3 (Publish Notifications): ${{ steps.step3.outputs.success || 'failed/skipped' }}" |
| 222 | + echo "==========================================" |
| 223 | +
|
| 224 | + if [ "${{ steps.step1.outputs.success }}" != "true" ]; then |
| 225 | + echo "❌ Release failed at Step 1 (Publish Images)" |
| 226 | + echo " Step 2 and Step 3 were skipped" |
| 227 | + elif [ "${{ steps.step2.outputs.success }}" != "true" ]; then |
| 228 | + echo "❌ Release failed at Step 2 (Generate Info)" |
| 229 | + echo " Step 3 was skipped" |
| 230 | + elif [ "${{ steps.step3.outputs.success }}" != "true" ]; then |
| 231 | + echo "❌ Release failed at Step 3 (Publish Notifications)" |
| 232 | + else |
| 233 | + echo "✅ All steps completed successfully!" |
| 234 | + fi |
| 235 | +
|
| 236 | + - name: Cleanup |
| 237 | + if: always() |
| 238 | + shell: bash |
| 239 | + run: | |
| 240 | + rm -rf ${PACKAGE_DIR} || true |
| 241 | + rm -f release_spec.yml || true |
| 242 | + echo "Cleanup completed" |
0 commit comments