Build & Push Cloudshell Images #124
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
name: Build & Push Cloudshell Images | |
on: | |
push: | |
branches: | |
- main | |
schedule: | |
# Run at 5am and 12pm PDT on weekdays | |
# 5am PDT is 12pm UTC | |
- cron: '0 12 * * 1-5' | |
# 12pm PDT is 7pm UTC | |
- cron: '0 19 * * 1-5' | |
workflow_dispatch: | |
inputs: | |
cloudshell-branch: | |
type: string | |
description: "CloudShell Branch to use for building images" | |
default: "master" | |
cloudshell-repository: | |
type: string | |
description: "CloudShell Repository to use for building images" | |
default: "Azure/CloudShell" | |
env: | |
REGISTRY: ghcr.io | |
CLOUDSHELL_REPO: ${{ inputs.cloudshell-repository || 'Azure/CloudShell' }} | |
CLOUDSHELL_BRANCH: ${{ inputs.cloudshell-branch || 'master' }} | |
jobs: | |
build_and_push: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
packages: write | |
steps: | |
# Set up trivy. | |
- name: Maximize build space | |
# Skip this step if the cloudshell-branch is not master and the cloudshell-repository is not Azure/CloudShell. | |
if: ${{ env.CLOUDSHELL_BRANCH == 'master' && env.CLOUDSHELL_REPO == 'Azure/CloudShell' }} | |
uses: easimon/maximize-build-space@master | |
with: | |
root-reserve-mb: '16384' | |
temp-reserve-mb: '100' | |
swap-size-mb: '8192' | |
remove-dotnet: 'true' | |
remove-android: 'true' | |
remove-haskell: 'true' | |
remove-codeql: 'true' | |
# Download code. | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
with: | |
repository: "${{ env.CLOUDSHELL_REPO }}" | |
path: CloudShell | |
ref: "${{ env.CLOUDSHELL_BRANCH }}" | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Create temporary trivy directories | |
# Skip this step if the cloudshell-branch is not master and the cloudshell-repository is not Azure/CloudShell. | |
if: ${{ env.CLOUDSHELL_BRANCH == 'master' && env.CLOUDSHELL_REPO == 'Azure/CloudShell' }} | |
run: | | |
sudo mkdir $GITHUB_WORKSPACE/trivy-tmp | |
sudo mkdir $GITHUB_WORKSPACE/trivy-tmp/.cache | |
echo "TMPDIR=$GITHUB_WORKSPACE/trivy-tmp" >> $GITHUB_ENV | |
echo "TRIVY_CACHE_DIR=$GITHUB_WORKSPACE/trivy-tmp/.cache" >> $GITHUB_ENV | |
- name: Login to GHCR | |
uses: docker/login-action@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
username: ${{ github.actor}} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Generate Tag | |
id: tag | |
run: | | |
cd CloudShell | |
# Generate a tag based on the commit hash and current timestamp. | |
# It is possible that the master may not change, so timestamp ensures that the tag is unique. | |
# The format is <branch>-<commit hash>-<timestamp>. | |
echo "image_tag=$(git rev-parse --abbrev-ref HEAD)-$(git rev-parse --short HEAD)-$(date '+%Y%m%d-%H%M%S')" >> $GITHUB_OUTPUT | |
- name: Extract metadata labels for base image | |
id: base-meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY }}/surajssd/cloudshell/base | |
tags: | | |
type=raw,value=${{ steps.tag.outputs.image_tag }} | |
type=raw,value=latest,enable=${{ env.CLOUDSHELL_BRANCH == 'master' && env.CLOUDSHELL_REPO == 'Azure/CloudShell' }} | |
- name: Base image | |
uses: docker/build-push-action@v6 | |
with: | |
context: CloudShell | |
file: CloudShell/linux/base.Dockerfile | |
push: true | |
tags: ${{ steps.base-meta.outputs.tags }} | |
labels: ${{ steps.base-meta.outputs.labels }} | |
- name: Scan base image with Trivy | |
# Skip this step if the cloudshell-branch is not master and the cloudshell-repository is not Azure/CloudShell. | |
if: ${{ env.CLOUDSHELL_BRANCH == 'master' && env.CLOUDSHELL_REPO == 'Azure/CloudShell' }} | |
id: trivy-base-scan | |
uses: aquasecurity/trivy-action@0.20.0 | |
with: | |
scan-type: 'image' | |
image-ref: ${{ fromJSON(steps.base-meta.outputs.json).tags[0] }} | |
scanners: 'vuln,config' | |
severity: 'HIGH,CRITICAL' | |
- name: Extract metadata labels for tools image | |
id: tools-meta | |
uses: docker/metadata-action@v5 | |
with: | |
images: ${{ env.REGISTRY }}/surajssd/cloudshell/tools | |
tags: | | |
type=raw,value=${{ steps.tag.outputs.image_tag }} | |
type=raw,value=latest,enable=${{ env.CLOUDSHELL_BRANCH == 'master' && env.CLOUDSHELL_REPO == 'Azure/CloudShell' }} | |
- name: Tools image | |
uses: docker/build-push-action@v6 | |
with: | |
context: CloudShell | |
file: CloudShell/linux/tools.Dockerfile | |
push: true | |
build-args: IMAGE_LOCATION=${{ fromJSON(steps.base-meta.outputs.json).tags[0] }} | |
tags: ${{ steps.tools-meta.outputs.tags }} | |
labels: ${{ steps.tools-meta.outputs.labels }} | |
- name: Scan tools image with Trivy | |
# Skip this step if the cloudshell-branch is not master and the cloudshell-repository is not Azure/CloudShell. | |
if: ${{ env.CLOUDSHELL_BRANCH == 'master' && env.CLOUDSHELL_REPO == 'Azure/CloudShell' }} | |
id: trivy-tools-scan | |
uses: aquasecurity/trivy-action@0.20.0 | |
with: | |
scan-type: 'image' | |
image-ref: ${{ fromJSON(steps.tools-meta.outputs.json).tags[0] }} | |
scanners: 'vuln,config' | |
severity: 'HIGH,CRITICAL' |