LazyToolBox: cover gaps surfaced by Integration shard 2 #309
This file contains hidden or 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 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 }}" | |
| } | |
| ] | |
| } | |
| ] | |
| } |