Publish latest images to Docker Hub #135
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: Publish latest images to Docker Hub | |
on: | |
workflow_dispatch: | |
schedule: | |
- cron: "0 10 * * MON" | |
jobs: | |
# Sync the 'latest' tag from GAR to Docker Hub | |
# | |
# From your GitHub repo clock Settings. In the left menu, click Environments. | |
# Click New environment, set the name production, and click Configure environment. | |
# Check the "Required reviewers" box and enter at least one user or team name. | |
promote-latest: | |
if: (github.event_name == 'schedule') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') | |
runs-on: ubuntu-latest | |
environment: "production" | |
permissions: | |
contents: "read" | |
id-token: "write" | |
env: | |
WORKLOAD_IDENTITY_POOL_ID: projects/665270063338/locations/global/workloadIdentityPools/workspace-images-github-actions/providers/workspace-images-gha-provider | |
GAR_IMAGE_REGISTRY: europe-docker.pkg.dev | |
DH_IMAGE_REGISTRY: registry.hub.docker.com | |
IAM_SERVICE_ACCOUNT: [email protected] | |
SKOPEO_VERSION: 1 | |
steps: | |
- name: π₯ Checkout workspace-images | |
uses: actions/checkout@v4 | |
with: | |
repository: gitpod-io/workspace-images | |
- name: π§ Setup tools | |
run: | | |
sudo apt-get install python3-pip | |
sudo pip3 install yq | |
- name: π Setup skopeo | |
env: | |
SKOPEO_VERSION: ${{env.SKOPEO_VERSION}} | |
run: | | |
# Generate a temporal file to store skopeo auth | |
SKOPEO_AUTH_DIR=$(mktemp -d) | |
# to test locally | |
# export GITHUB_ENV=$(mktemp) | |
echo "SKOPEO_AUTH_DIR=${SKOPEO_AUTH_DIR}" >> $GITHUB_ENV | |
# Build a fake skopeo script to run a container | |
cat <<EOF | sudo tee /usr/local/bin/skopeo > /dev/null | |
#/bin/bash | |
docker run --rm \ | |
-v $SKOPEO_AUTH_DIR:/skopeo.auth \ | |
-e REGISTRY_AUTH_FILE=/skopeo.auth/auth \ | |
quay.io/skopeo/stable:v$SKOPEO_VERSION "\$@" | |
EOF | |
sudo chmod +x /usr/local/bin/skopeo | |
# don't fail parsing the file while it contains empty creds the first time | |
echo "{}" > $SKOPEO_AUTH_DIR/auth | |
- name: βοΈ Set up Cloud SDK | |
uses: google-github-actions/[email protected] | |
with: | |
version: 393.0.0 | |
- name: π Authenticate to Google Cloud | |
id: "auth" | |
uses: google-github-actions/[email protected] | |
with: | |
token_format: "access_token" | |
workload_identity_provider: ${{env.WORKLOAD_IDENTITY_POOL_ID}} | |
service_account: ${{env.IAM_SERVICE_ACCOUNT}} | |
- name: βπ½ Login to GAR using skopeo | |
env: | |
SKOPEO_AUTH_DIR: ${{env.SKOPEO_AUTH_DIR}} | |
run: | | |
sudo -E skopeo login -u oauth2accesstoken --password=${{ steps.auth.outputs.access_token }} ${{env.GAR_IMAGE_REGISTRY}} | |
- name: βπ½ Login to Docker Hub using skopeo | |
env: | |
docker_user: ${{ secrets.DOCKERHUB_USER_NAME }} | |
docker_password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }} | |
SKOPEO_AUTH_DIR: ${{env.SKOPEO_AUTH_DIR}} | |
run: | | |
sudo -E skopeo login -u ${{ env.docker_user }} --password=${{ env.docker_password }} ${{ env.DH_IMAGE_REGISTRY }} | |
- name: π³ Sync latest tag of images to Docker Hub | |
env: | |
SKOPEO_AUTH_DIR: ${{env.SKOPEO_AUTH_DIR}} | |
run: | | |
IMAGES=$(cat .github/promote-images.yml | yq '."europe-docker.pkg.dev/gitpod-artifacts/docker-dev"."images-by-tag-regex"|keys[]' -r) | |
for IMAGE in $IMAGES; | |
do | |
sudo -E skopeo copy --format=oci --dest-oci-accept-uncompressed-layers --retry-times=2 \ | |
docker://${{ env.GAR_IMAGE_REGISTRY }}/gitpod-artifacts/docker-dev/$IMAGE:latest \ | |
docker://${{ env.DH_IMAGE_REGISTRY }}/gitpod/$IMAGE:latest | |
done | |
notify: | |
if: always() && ((github.event_name == 'schedule') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')) | |
needs: promote-latest | |
runs-on: ubuntu-latest | |
steps: | |
- name: The release was successful | |
id: slack-success | |
if: needs.promote-latest.result == 'success' | |
uses: slackapi/[email protected] | |
with: | |
payload: | | |
{ | |
"text": "The release was successful :rocket:" | |
} | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.RELEASE_NOTIFY_WEBHOOK }} | |
- name: The release was not successful | |
id: slack-failure | |
if: needs.promote-latest.result != 'success' | |
uses: slackapi/[email protected] | |
with: | |
payload: | | |
{ | |
"text": "${{ format('The release had trouble :construction:, the result was: {0}', needs.promote-latest.result) }}" | |
} | |
env: | |
SLACK_WEBHOOK_URL: ${{ secrets.RELEASE_NOTIFY_WEBHOOK }} |