Skip to content

Commit 388b4a5

Browse files
committed
Merge branch 'release_25.0' into release_25.1
2 parents cdf98a0 + 522546c commit 388b4a5

7 files changed

Lines changed: 200 additions & 46 deletions

File tree

.github/workflows/build_container_image.yaml

Lines changed: 146 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,16 @@ jobs:
7575
name: Build container image for Galaxy repos
7676
runs-on: ubuntu-latest
7777
if: github.repository_owner == 'galaxyproject'
78+
outputs:
79+
tag: ${{ steps.branch.outputs.name }}
80+
version: ${{ steps.version.outputs.version }}
7881
steps:
79-
- uses: actions/checkout@v5
82+
- uses: actions/checkout@v6
8083
with:
8184
persist-credentials: false
85+
- uses: actions/setup-python@v6
86+
with:
87+
python-version: '3.12'
8288
# https://stackoverflow.com/questions/59810838/how-to-get-the-short-sha-for-the-github-workflow
8389
- name: Set outputs
8490
id: commit
@@ -94,6 +100,11 @@ jobs:
94100
echo "name=${GITHUB_REF#refs/heads/release_}-auto" >> $GITHUB_OUTPUT
95101
fi
96102
shell: bash
103+
- name: Get the current Galaxy version
104+
id: version
105+
run: |
106+
version=$(python3 -c "import lib.galaxy.version; print(lib.galaxy.version.VERSION)")
107+
echo "version=$version" >> $GITHUB_OUTPUT
97108
- name: Build container image
98109
run: docker build . --build-arg GIT_COMMIT=$(git rev-parse HEAD) --build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') --build-arg IMAGE_TAG=${{ steps.branch.outputs.name }} -t galaxy/galaxy-min:${{ steps.branch.outputs.name }} -t quay.io/galaxyproject/galaxy-min:${{ steps.branch.outputs.name }} -f .k8s_ci.Dockerfile
99110
- name: Create auto-expiring one for per-commit auto repository
@@ -122,3 +133,137 @@ jobs:
122133
with:
123134
args: push galaxy/galaxy-min:${{ steps.branch.outputs.name }}
124135

136+
smoke-test:
137+
name: Try installing the new image
138+
runs-on: ubuntu-latest
139+
needs: [ build ]
140+
steps:
141+
- name: Start k8s locally
142+
uses: jupyterhub/action-k3s-helm@v4
143+
with:
144+
k3s-version: v1.32.0+k3s1 # releases: https://github.com/k3s-io/k3s/tags
145+
metrics-enabled: false
146+
traefik-enabled: false
147+
- name: Verify function of k8s, kubectl, and helm
148+
run: |
149+
echo "kubeconfig: $KUBECONFIG"
150+
kubectl version
151+
kubectl get pods --all-namespaces
152+
helm version
153+
helm list
154+
- name: Add the Galaxy Helm repository
155+
run: helm repo add galaxy https://github.com/CloudVE/helm-charts/raw/master
156+
- name: Install the Galaxy dependencies
157+
run: |
158+
helm install galaxy-deps galaxy/galaxy-deps \
159+
--namespace galaxy-deps \
160+
--create-namespace \
161+
--set cvmfs.cvmfscsi.cache.alien.enabled=false \
162+
--wait \
163+
--timeout=1200s
164+
- name: Install Galaxy using the image we just pushed
165+
run: |
166+
helm install galaxy galaxy/galaxy \
167+
--namespace galaxy \
168+
--create-namespace \
169+
--set persistence.accessMode="ReadWriteOnce" \
170+
--set resources.requests.memory=0Mi,resources.requests.cpu=0m \
171+
--set image.tag=${{ needs.build.outputs.tag }} \
172+
--set webHandlers.startupProbe.initialDelaySeconds=120 \
173+
--set webHandlers.startupProbe.periodSeconds=15 \
174+
--set webHandlers.startupProbe.failureThreshold=72 \
175+
--wait \
176+
--timeout=1200s
177+
- name: Debug deployment on failure
178+
if: failure()
179+
run: |
180+
echo "=== Deployment failed, gathering debug information ==="
181+
182+
echo "=== All pods in galaxy namespace ==="
183+
kubectl get pods -n galaxy -o wide
184+
185+
echo "=== All pods in galaxy-deps namespace ==="
186+
kubectl get pods -n galaxy-deps -o wide
187+
188+
echo "=== CSI Drivers ==="
189+
kubectl get csidriver
190+
191+
echo "=== Storage Classes ==="
192+
kubectl get sc
193+
194+
echo "=== PVCs in galaxy namespace ==="
195+
kubectl get pvc -n galaxy
196+
197+
echo "=== PVCs in galaxy-deps namespace ==="
198+
kubectl get pvc -n galaxy-deps
199+
200+
echo "=== Recent events in galaxy namespace ==="
201+
kubectl get events -n galaxy --sort-by='.lastTimestamp' | tail -50
202+
203+
echo "=== Recent events in galaxy-deps namespace ==="
204+
kubectl get events -n galaxy-deps --sort-by='.lastTimestamp' | tail -50
205+
206+
echo "=== Describe pending/failed pods in galaxy namespace ==="
207+
for pod in $(kubectl get pods -n galaxy --field-selector=status.phase!=Running,status.phase!=Succeeded -o name 2>/dev/null); do
208+
echo "--- Describing $pod ---"
209+
kubectl describe -n galaxy $pod
210+
done
211+
212+
echo "=== Describe pending/failed pods in galaxy-deps namespace ==="
213+
for pod in $(kubectl get pods -n galaxy-deps --field-selector=status.phase!=Running,status.phase!=Succeeded -o name 2>/dev/null); do
214+
echo "--- Describing $pod ---"
215+
kubectl describe -n galaxy-deps $pod
216+
done
217+
- name: Check the version
218+
run: |
219+
kubectl get svc -n galaxy
220+
kubectl describe svc -n galaxy galaxy-nginx
221+
address=$(kubectl get svc -n galaxy galaxy-nginx -o jsonpath="http://{.spec.clusterIP}:{.spec.ports[0].port}/galaxy/api/version")
222+
echo "Address is $address"
223+
appVersion=${{ needs.build.outputs.version }}
224+
apiVersion=$(curl $address | jq -r '"\(.version_major).\(.version_minor)"')
225+
echo "appVersion: $appVersion"
226+
echo "apiVersion: $apiVersion"
227+
if [ "$appVersion" != "$apiVersion" ]; then
228+
exit 1
229+
fi
230+
231+
pr:
232+
name: Create a PR to update the Galaxy Helm chart when a release is tagged
233+
runs-on: ubuntu-latest
234+
needs: [smoke-test, build]
235+
if: startsWith(github.ref, 'refs/tags/')
236+
steps:
237+
- name: Checkout Galaxy Helm chart
238+
uses: actions/checkout@v6
239+
with:
240+
repository: galaxyproject/galaxy-helm
241+
token: ${{ secrets.GITHUB_TOKEN }}
242+
persist-credentials: true
243+
244+
- name: Update Chart.yaml appVersion
245+
run: |
246+
sed -i "s/^appVersion:.*/appVersion: \"${{ needs.build.outputs.version }}\"/" galaxy/Chart.yaml
247+
248+
- name: Update values.yaml image.tag
249+
run: |
250+
sed -i "s/^ tag:.*/ tag: \"${{ needs.build.outputs.tag }}\"/" galaxy/values.yaml
251+
252+
- name: Create Pull Request
253+
uses: peter-evans/create-pull-request@v7
254+
with:
255+
token: ${{ secrets.GALAXY_HELM_PULL_REQUEST_TOKEN }}
256+
commit-message: "Update Galaxy to version ${{ needs.build.outputs.version }}"
257+
title: "Update Galaxy to version ${{ needs.build.outputs.version }}"
258+
body: |
259+
This PR updates the Galaxy Helm chart to use the new Galaxy release.
260+
261+
Changes:
262+
- appVersion: ${{ needs.build.outputs.version }}
263+
- image.tag: ${{ needs.build.outputs.tag }}
264+
265+
Triggered by: ${{ github.ref }}
266+
branch: update-galaxy-${{ needs.build.outputs.version }}
267+
delete-branch: true
268+
labels: patch
269+

client/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@galaxyproject/galaxy-client",
3-
"version": "24.0.0",
3+
"version": "25.0.4",
44
"description": "Galaxy client application build system",
55
"keywords": [
66
"galaxy"

lib/galaxy/dependencies/pinned-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ edam-ontology==1.25.2
6767
email-validator==2.3.0
6868
et-xmlfile==2.0.0
6969
exceptiongroup==1.3.0 ; python_full_version < '3.11'
70-
fastapi-slim==0.118.0
70+
fastapi==0.118.0
7171
filelock==3.19.1
7272
fissix==24.4.24
7373
frozenlist==1.7.0

lib/galaxy/tool_util/deps/mulled/get_tests.py

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,6 @@ def get_anaconda_url(container, anaconda_channel="bioconda"):
108108
return f"https://anaconda.org/{anaconda_channel}/{name[0]}/{name[1]}/download/linux-64/{'-'.join(name)}.tar.bz2"
109109

110110

111-
def prepend_anaconda_url(url):
112-
"""
113-
Take a partial url and prepend 'https://anaconda.org'
114-
"""
115-
return f"https://anaconda.org{url}"
116-
117-
118111
def get_test_from_anaconda(url: str) -> Optional[Dict[str, Any]]:
119112
"""
120113
Given the URL of an anaconda tarball, return tests
@@ -132,20 +125,26 @@ def get_test_from_anaconda(url: str) -> Optional[Dict[str, Any]]:
132125
return None
133126

134127

135-
def find_anaconda_versions(name, anaconda_channel="bioconda"):
128+
def find_anaconda_download_url(
129+
name: str, version: str, build: Optional[str] = None, anaconda_channel: str = "bioconda"
130+
) -> Optional[str]:
136131
"""
137-
Find a list of available anaconda versions for a given container name
132+
Find the anaconda download url for a given package.
138133
"""
139134
r = requests.get(
140-
f"https://anaconda.org/{anaconda_channel}/{name}/files",
135+
f"https://api.anaconda.org/package/{anaconda_channel}/{name}/files",
141136
timeout=MULLED_SOCKET_TIMEOUT,
142137
)
143138
r.raise_for_status()
144-
urls = []
145-
for line in r.text.splitlines():
146-
if "download/linux" in line:
147-
urls.append(line.split('"')[1])
148-
return urls
139+
package_files = r.json()
140+
for package_file in reversed(package_files):
141+
if (
142+
package_file["version"] == version
143+
and (build is None or package_file["attrs"]["build"] == build)
144+
and package_file["attrs"]["subdir"] in ["linux-64", "noarch"]
145+
):
146+
return f"https:{package_file['download_url']}"
147+
return None
149148

150149

151150
def open_recipe_file(file, recipes_path=None, github_repo="bioconda/bioconda-recipes"):
@@ -211,50 +210,55 @@ def deep_test_search(
211210
"""
212211
Look in bioconda-recipes repo as well as anaconda for the tests, checking in multiple possible locations. If no test is found for the specified version, search if other package versions have a test available.
213212
"""
214-
name = split_container_name(container)
213+
name_tuple = split_container_name(container)
214+
assert len(name_tuple) in (2, 3)
215+
name = name_tuple[0]
216+
version = name_tuple[1]
217+
build = name_tuple[2] if len(name_tuple) == 3 else None
215218
for f in [
216219
(
217220
get_commands_from_yaml,
218221
open_recipe_file,
219-
(f"recipes/{name[0]}/{name[1]}/meta.yaml", recipes_path, github_repo),
222+
(f"recipes/{name}/{version}/meta.yaml", recipes_path, github_repo),
220223
container,
221224
),
222225
(
223226
get_run_test,
224227
open_recipe_file,
225-
(f"recipes/{name[0]}/{name[1]}/run_test.sh", recipes_path, github_repo),
228+
(f"recipes/{name}/{version}/run_test.sh", recipes_path, github_repo),
226229
container,
227230
),
228231
(
229232
get_commands_from_yaml,
230233
open_recipe_file,
231-
(f"recipes/{name[0]}/meta.yaml", recipes_path, github_repo),
234+
(f"recipes/{name}/meta.yaml", recipes_path, github_repo),
232235
container,
233236
),
234-
(get_run_test, open_recipe_file, (f"recipes/{name[0]}/run_test.sh", recipes_path, github_repo), container),
237+
(get_run_test, open_recipe_file, (f"recipes/{name}/run_test.sh", recipes_path, github_repo), container),
235238
(get_test_from_anaconda, get_anaconda_url, (container, anaconda_channel), container),
236239
]:
237240
result = try_a_func(*f)
238241
if result:
239242
return result
240243

241-
versions = get_alternative_versions(f"recipes/{name[0]}", "meta.yaml", recipes_path, github_repo)
242-
for version in versions:
243-
result = try_a_func(get_commands_from_yaml, open_recipe_file, (version, recipes_path, github_repo), container)
244+
alt_versions = get_alternative_versions(f"recipes/{name}", "meta.yaml", recipes_path, github_repo)
245+
for alt_version in alt_versions:
246+
result = try_a_func(
247+
get_commands_from_yaml, open_recipe_file, (alt_version, recipes_path, github_repo), container
248+
)
244249
if result:
245250
return result
246251

247-
versions = get_alternative_versions(f"recipes/{name[0]}", "run_test.sh", recipes_path, github_repo)
248-
for version in versions:
249-
result = try_a_func(get_run_test, open_recipe_file, (version, recipes_path, github_repo), container)
252+
alt_versions = get_alternative_versions(f"recipes/{name}", "run_test.sh", recipes_path, github_repo)
253+
for alt_version in alt_versions:
254+
result = try_a_func(get_run_test, open_recipe_file, (alt_version, recipes_path, github_repo), container)
250255
if result:
251256
return result
252257

253-
versions = find_anaconda_versions(name[0], anaconda_channel)
254-
for version in versions:
255-
result = try_a_func(get_test_from_anaconda, prepend_anaconda_url, (version,), container)
256-
if result:
257-
return result
258+
url = find_anaconda_download_url(name, version, build=build, anaconda_channel=anaconda_channel)
259+
result = try_a_func(get_test_from_anaconda, lambda x: x, (url,), container)
260+
if result:
261+
return result
258262

259263
# if everything fails
260264
return {"container": container}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
},
1818
"homepage": "https://github.com/galaxyproject/galaxy#readme",
1919
"dependencies": {
20-
"@galaxyproject/galaxy-client": "^24.0.0",
20+
"@galaxyproject/galaxy-client": "^25.0.4",
2121
"cpy-cli": "^5.0.0"
2222
},
2323
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies = [
3737
"docutils!=0.17,!=0.17.1",
3838
"dparse",
3939
"edam-ontology",
40-
"fastapi-slim>=0.111.0",
40+
"fastapi>=0.111.0",
4141
"fissix",
4242
"fs",
4343
"future>=1.0.0", # Python 3.12 support

test/unit/tool_util/mulled/test_get_tests.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from galaxy.tool_util.deps.mulled.get_tests import (
44
deep_test_search,
5-
find_anaconda_versions,
5+
find_anaconda_download_url,
66
get_alternative_versions,
77
get_anaconda_url,
88
get_commands_from_yaml,
@@ -11,7 +11,6 @@
1111
hashed_test_search,
1212
main_test_search,
1313
open_recipe_file,
14-
prepend_anaconda_url,
1514
)
1615
from galaxy.util import smart_str
1716
from ..util import external_dependency_management
@@ -49,11 +48,6 @@ def test_get_anaconda_url():
4948
assert url == "https://anaconda.org/bioconda/samtools/1.7/download/linux-64/samtools-1.7-1.tar.bz2"
5049

5150

52-
def test_prepend_anaconda_url():
53-
url = prepend_anaconda_url("/bioconda/samtools/0.1.12/download/linux-64/samtools-0.1.12-2.tar.bz2")
54-
assert url == "https://anaconda.org/bioconda/samtools/0.1.12/download/linux-64/samtools-0.1.12-2.tar.bz2"
55-
56-
5751
@external_dependency_management
5852
def test_get_test_from_anaconda():
5953
# test old fashion tar.bz2 package
@@ -81,9 +75,20 @@ def test_get_test_from_anaconda():
8175

8276

8377
@external_dependency_management
84-
def test_find_anaconda_versions():
85-
versions = find_anaconda_versions("2pg_cartesian")
86-
assert "/bioconda/2pg_cartesian/1.0.1/download/linux-64/2pg_cartesian-1.0.1-0.tar.bz2" in versions
78+
def test_find_anaconda_download_url():
79+
download_url = find_anaconda_download_url("2pg_cartesian", "1.0.0")
80+
assert download_url is None
81+
download_url = find_anaconda_download_url("2pg_cartesian", "1.0.1")
82+
assert download_url is not None
83+
assert download_url.startswith(
84+
"https://api.anaconda.org/download/bioconda/2pg_cartesian/1.0.1/linux-64/2pg_cartesian-1.0.1-"
85+
)
86+
download_url = find_anaconda_download_url("2pg_cartesian", "1.0.1", "0")
87+
assert download_url is not None
88+
assert (
89+
download_url
90+
== "https://api.anaconda.org/download/bioconda/2pg_cartesian/1.0.1/linux-64/2pg_cartesian-1.0.1-0.tar.bz2"
91+
)
8792

8893

8994
@external_dependency_management

0 commit comments

Comments
 (0)