Skip to content

LazyToolBox: clear _tool_versions_by_id + lineage on remove_tool_by_id #328

LazyToolBox: clear _tool_versions_by_id + lineage on remove_tool_by_id

LazyToolBox: clear _tool_versions_by_id + lineage on remove_tool_by_id #328

name: Build Container Image
on:
push:
branches:
- dev
- release_*
tags:
- v*
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ghcrbuild:
name: Build container image for GHCR
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
# https://stackoverflow.com/questions/59810838/how-to-get-the-short-sha-for-the-github-workflow
- name: Set outputs
id: commit
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Set branch name
id: branch
run: |
if [[ "$GITHUB_REF" == "refs/tags/"* ]]; then
echo "name=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == "refs/heads/dev" ]]; then
echo "name=dev" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == "refs/heads/release_"* ]]; then
echo "name=${GITHUB_REF#refs/heads/release_}-auto" >> $GITHUB_OUTPUT
fi
shell: bash
- name: Extract metadata for container image
id: meta
uses: docker/metadata-action@v6
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=${{steps.branch.outputs.name}}
- name: Build args
id: buildargs
run: |
echo "gitcommit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "builddate=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
with:
platforms: linux/amd64
- name: Login to GHCR
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push container image to ghcr
uses: docker/build-push-action@v7
with:
build-args: |
GIT_COMMIT=${{ steps.buildargs.outputs.gitcommit }}
BUILD_DATE=${{ steps.buildargs.outputs.builddate }}
IMAGE_TAG=${{ steps.branch.outputs.name }}
file: .k8s_ci.Dockerfile
push: true
context: .
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64
build:
name: Build container image for Galaxy repos
runs-on: ubuntu-latest
if: github.repository_owner == 'galaxyproject'
outputs:
tag: ${{ steps.branch.outputs.name }}
version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- uses: actions/setup-python@v6
with:
python-version: '3.12'
# https://stackoverflow.com/questions/59810838/how-to-get-the-short-sha-for-the-github-workflow
- name: Set outputs
id: commit
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Set branch name
id: branch
run: |
if [[ "$GITHUB_REF" == "refs/tags/"* ]]; then
echo "name=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == "refs/heads/dev" ]]; then
echo "name=dev" >> $GITHUB_OUTPUT
elif [[ "$GITHUB_REF" == "refs/heads/release_"* ]]; then
echo "name=${GITHUB_REF#refs/heads/release_}-auto" >> $GITHUB_OUTPUT
fi
shell: bash
- name: Get the current Galaxy version
id: version
run: |
version=$(PYTHONPATH=lib python3 -c "from galaxy.version import VERSION; print(VERSION)")
echo "version=$version" >> $GITHUB_OUTPUT
- name: Build args
id: buildargs
run: |
echo "gitcommit=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
echo "builddate=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Login to quay.io
uses: docker/login-action@v4
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Login to DockerHub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Build and push galaxy-min image
uses: docker/build-push-action@v7
with:
context: .
file: .k8s_ci.Dockerfile
push: true
build-args: |
GIT_COMMIT=${{ steps.buildargs.outputs.gitcommit }}
BUILD_DATE=${{ steps.buildargs.outputs.builddate }}
IMAGE_TAG=${{ steps.branch.outputs.name }}
tags: |
galaxy/galaxy-min:${{ steps.branch.outputs.name }}
quay.io/galaxyproject/galaxy-min:${{ steps.branch.outputs.name }}
- name: Create Dockerfile for auto-expiring image
run: echo "FROM galaxy/galaxy-min:${{ steps.branch.outputs.name }}" > /tmp/Dockerfile.auto
- name: Build and push auto-expiring per-commit image
uses: docker/build-push-action@v7
with:
file: /tmp/Dockerfile.auto
push: true
tags: quay.io/galaxyproject/galaxy-k8s-auto:${{ steps.commit.outputs.sha_short }}
labels: quay.expires-after=90d
smoke-test:
name: Try installing the new image
runs-on: ubuntu-latest
needs: [ build ]
steps:
- name: Start k8s locally
uses: jupyterhub/action-k3s-helm@v4
with:
k3s-version: v1.32.0+k3s1 # releases: https://github.com/k3s-io/k3s/tags
metrics-enabled: false
traefik-enabled: false
- name: Verify function of k8s, kubectl, and helm
run: |
echo "kubeconfig: $KUBECONFIG"
kubectl version
kubectl get pods --all-namespaces
helm version
helm list
- name: Add the Galaxy Helm repository
run: helm repo add galaxy https://github.com/CloudVE/helm-charts/raw/master
- name: Install the Galaxy dependencies
run: |
helm install galaxy-deps galaxy/galaxy-deps \
--namespace galaxy-deps \
--create-namespace \
--set cvmfs.cvmfscsi.cache.alien.enabled=false \
--wait \
--timeout=1200s
- name: Install Galaxy using the image we just pushed
run: |
helm install galaxy galaxy/galaxy \
--namespace galaxy \
--create-namespace \
--set persistence.accessMode="ReadWriteOnce" \
--set resources.requests.memory=0Mi,resources.requests.cpu=0m \
--set image.tag=${{ needs.build.outputs.tag }} \
--wait \
--timeout=1200s
- name: Debug deployment on failure
if: failure()
run: |
echo "=== Deployment failed, gathering debug information ==="
echo "=== All pods in galaxy namespace ==="
kubectl get pods -n galaxy -o wide
echo "=== All pods in galaxy-deps namespace ==="
kubectl get pods -n galaxy-deps -o wide
echo "=== CSI Drivers ==="
kubectl get csidriver
echo "=== Storage Classes ==="
kubectl get sc
echo "=== PVCs in galaxy namespace ==="
kubectl get pvc -n galaxy
echo "=== PVCs in galaxy-deps namespace ==="
kubectl get pvc -n galaxy-deps
echo "=== Recent events in galaxy namespace ==="
kubectl get events -n galaxy --sort-by='.lastTimestamp' | tail -50
echo "=== Recent events in galaxy-deps namespace ==="
kubectl get events -n galaxy-deps --sort-by='.lastTimestamp' | tail -50
echo "=== Describe pending/failed pods in galaxy namespace ==="
for pod in $(kubectl get pods -n galaxy --field-selector=status.phase!=Running,status.phase!=Succeeded -o name 2>/dev/null); do
echo "--- Describing $pod ---"
kubectl describe -n galaxy $pod
done
echo "=== Describe pending/failed pods in galaxy-deps namespace ==="
for pod in $(kubectl get pods -n galaxy-deps --field-selector=status.phase!=Running,status.phase!=Succeeded -o name 2>/dev/null); do
echo "--- Describing $pod ---"
kubectl describe -n galaxy-deps $pod
done
- name: Check the version
run: |
kubectl get svc -n galaxy
kubectl describe svc -n galaxy galaxy-nginx
address=$(kubectl get svc -n galaxy galaxy-nginx -o jsonpath="http://{.spec.clusterIP}:{.spec.ports[0].port}/galaxy/api/version")
echo "Address is $address"
appVersion=${{ needs.build.outputs.version }}
apiVersion=$(curl $address | jq -r '"\(.version_major).\(.version_minor)"')
echo "appVersion: $appVersion"
echo "apiVersion: $apiVersion"
if [ "$appVersion" != "$apiVersion" ]; then
exit 1
fi
- name: Check client build is served
run: |
base_url=$(kubectl get svc -n galaxy galaxy-nginx -o jsonpath="http://{.spec.clusterIP}:{.spec.ports[0].port}")
css_url="${base_url}/galaxy/static/dist/base.css"
echo "Checking client build at $css_url"
status_code=$(curl -s -o /dev/null -w "%{http_code}" "$css_url")
echo "Status code: $status_code"
if [ "$status_code" != "200" ]; then
echo "ERROR: Failed to fetch base.css (status: $status_code)"
echo "This indicates the client build was not properly included in the image"
exit 1
fi
echo "Client build is properly served"
pr:
name: Create a PR to update the Galaxy Helm chart when a release is tagged
runs-on: ubuntu-latest
needs: [smoke-test, build]
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Checkout Galaxy Helm chart
uses: actions/checkout@v6
with:
repository: galaxyproject/galaxy-helm
persist-credentials: false
- name: Update Chart.yaml appVersion
run: |
sed -i "s/^appVersion:.*/appVersion: \"${{ needs.build.outputs.version }}\"/" galaxy/Chart.yaml
- name: Update values.yaml image.tag
run: |
sed -i "s/^ tag:.*/ tag: \"${{ needs.build.outputs.tag }}\"/" galaxy/values.yaml
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
token: ${{ secrets.GALAXY_HELM_PULL_REQUEST_TOKEN }}
commit-message: "Update Galaxy to version ${{ needs.build.outputs.version }}"
title: "Update Galaxy to version ${{ needs.build.outputs.version }}"
body: |
This PR updates the Galaxy Helm chart to use the new Galaxy release.
Changes:
- appVersion: ${{ needs.build.outputs.version }}
- image.tag: ${{ needs.build.outputs.tag }}
Triggered by: ${{ github.ref }}
branch: update-galaxy-${{ needs.build.outputs.version }}
delete-branch: true
labels: patch
notify-failure:
name: Notify Slack on failure
runs-on: ubuntu-latest
needs: [build, smoke-test]
if: ${{ always() && (needs.build.result == 'failure' || needs.smoke-test.result == 'failure') }}
steps:
- name: Determine which job failed
id: failure-info
run: |
if [[ "${{ needs.build.result }}" == "failure" ]]; then
echo "failed_job=Docker image build" >> $GITHUB_OUTPUT
elif [[ "${{ needs.smoke-test.result }}" == "failure" ]]; then
echo "failed_job=Smoke test" >> $GITHUB_OUTPUT
fi
- name: Send Slack notification
uses: slackapi/slack-github-action@v3.0.2
with:
webhook: ${{ secrets.K8S_SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": ":x: *Build Container Image Failed*",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": ":x: Build Container Image Failed",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Repository:*\n${{ github.repository }}"
},
{
"type": "mrkdwn",
"text": "*Branch/Tag:*\n${{ github.ref_name }}"
},
{
"type": "mrkdwn",
"text": "*Failed Job:*\n${{ steps.failure-info.outputs.failed_job }}"
},
{
"type": "mrkdwn",
"text": "*Triggered by:*\n${{ github.actor }}"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Workflow Run",
"emoji": true
},
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
]
}
]
}