Skip to content

Build & Push Cloudshell Images #129

Build & Push Cloudshell Images

Build & Push Cloudshell Images #129

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'