mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge branch 'dev' of https://github.com/galaxyproject/galaxy into jupytool
This commit is contained in:
+1
-1
@@ -1,2 +1,2 @@
|
||||
exclude=$(sed -e 's|^|./|' -e 's|/$||' .ci/flake8_blacklist.txt | paste -s -d ',' - )
|
||||
exclude=$(sed -e 's|^|./|' -e 's|/$||' .ci/flake8_ignorelist.txt | paste -s -d ',' - )
|
||||
autopep8 -i -r --exclude $exclude --select E11,E101,E127,E201,E202,E22,E301,E302,E303,E304,E306,E711,W291,W292,W293,W391 ./lib/ ./test/
|
||||
|
||||
+34
-5
@@ -1,16 +1,45 @@
|
||||
#!/bin/sh
|
||||
case "$1" in
|
||||
galaxy|"")
|
||||
SCRIPT=./run.sh
|
||||
PORT=8080
|
||||
LOGFILE=galaxy.log
|
||||
GRAVITY_LOGFILE=database/gravity/log/gunicorn.log
|
||||
SUPERVISORD_LOGFILE=database/gravity/supervisor/supervisord.log
|
||||
;;
|
||||
reports)
|
||||
SCRIPT=./run_reports.sh
|
||||
PORT=9001
|
||||
LOGFILE=reports_webapp.log
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unrecognized app"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
TRIES=120
|
||||
URL=http://localhost:8080
|
||||
URL=http://localhost:$PORT
|
||||
EXIT_CODE=1
|
||||
i=0
|
||||
echo "Testing for correct startup:"
|
||||
bash run.sh --daemon && \
|
||||
$SCRIPT --daemon && \
|
||||
while [ "$i" -le $TRIES ]; do
|
||||
curl "$URL" && EXIT_CODE=0 && break
|
||||
curl --max-time 1 "$URL" && EXIT_CODE=0 && break
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
kill -9 "$(cat galaxy.pid)"
|
||||
$SCRIPT --skip-wheels --stop-daemon
|
||||
echo "exit code:$EXIT_CODE, showing startup log:"
|
||||
cat galaxy.log
|
||||
if [ -f "$LOGFILE" ]; then
|
||||
cat "$LOGFILE"
|
||||
elif [ ! -f "$LOGFILE" -a -f "$GRAVITY_LOGFILE" ]; then
|
||||
echo "Warning: $LOGFILE does not exist, showing gravity startup log instead"
|
||||
cat "$GRAVITY_LOGFILE"
|
||||
elif [ ! -f "$LOGFILE" -a ! -f "$GRAVITY_LOGFILE" -a -f "$SUPERVISORD_LOGFILE" ]; then
|
||||
echo "Warning: $LOGFILE and $GRAVITY_LOGFILE do not exist, showing supervisord startup log instead"
|
||||
cat "$SUPERVISORD_LOGFILE"
|
||||
else
|
||||
echo "ERROR: No log files found!"
|
||||
ls -lR database/gravity
|
||||
fi
|
||||
exit $EXIT_CODE
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
.git
|
||||
.tox
|
||||
.venv
|
||||
.venv3
|
||||
packages/*/.venv
|
||||
packages/*/build
|
||||
packages/*/dist
|
||||
packages/venv
|
||||
node_modules
|
||||
database
|
||||
doc/build
|
||||
doc/source/conf.py
|
||||
eggs
|
||||
lib/galaxy/util/jstree.py
|
||||
lib/galaxy/web/proxy/js/node_modules
|
||||
static/maps
|
||||
static/scripts
|
||||
build
|
||||
dist
|
||||
@@ -0,0 +1,20 @@
|
||||
.git
|
||||
.tox
|
||||
.venv
|
||||
.venv3
|
||||
packages/*/.venv
|
||||
packages/*/build
|
||||
packages/*/dist
|
||||
packages/venv
|
||||
node_modules
|
||||
database
|
||||
doc/build
|
||||
doc/source/conf.py
|
||||
eggs
|
||||
lib/galaxy/util/jstree.py
|
||||
lib/galaxy/web/proxy/js/node_modules
|
||||
static/maps
|
||||
static/scripts
|
||||
test/functional/tools/cwl_tools/v1.?/
|
||||
build
|
||||
dist
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
flake8 --exclude $(paste -sd, .ci/flake8_blacklist.txt) .
|
||||
flake8 --exclude $(paste -sd, .ci/flake8_ignorelist.txt) .
|
||||
|
||||
# Apply stricter rules for the directories shared with Pulsar
|
||||
flake8 --ignore=D --max-line-length=150 lib/galaxy/jobs/runners/util/
|
||||
flake8 --ignore=E203,D --max-line-length=150 lib/galaxy/jobs/runners/util/
|
||||
|
||||
@@ -17,5 +17,5 @@ if [ "$1" = "--include" ];
|
||||
then
|
||||
flake8 $args $(paste -sd' ' .ci/flake8_docstrings_include_list.txt)
|
||||
else
|
||||
flake8 $args --exclude $(paste -sd, .ci/flake8_blacklist.txt) .
|
||||
flake8 $args --exclude $(paste -sd, .ci/flake8_ignorelist.txt) .
|
||||
fi
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
api
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
./run_tests.sh --dockerize --db postgres --clean_pyc --skip_flakey_fails -api "$@"
|
||||
@@ -1 +0,0 @@
|
||||
framework
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
./run_tests.sh --dockerize --db postgres --clean_pyc --framework "$@"
|
||||
@@ -1 +0,0 @@
|
||||
integration
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
DOCKER_RUN_EXTRA_ARGS="--privileged" ./run_tests.sh --dockerize --db postgres --clean_pyc --integration "$@"
|
||||
@@ -1 +0,0 @@
|
||||
main-tools
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
./run_tests.sh --dockerize --db postgres --clean_pyc -main "$@"
|
||||
@@ -1,24 +0,0 @@
|
||||
FROM toolshed/requirements
|
||||
LABEL maintainer="John Chilton <jmchilton@gmail.com>"
|
||||
|
||||
RUN apt-get -qq update && \
|
||||
apt-get install --no-install-recommends -y postgresql-client python-pip libffi-dev python-cffi && \
|
||||
apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
ENV GALAXY_ROOT=/galaxy \
|
||||
GALAXY_CONFIG_OVERRIDE_ADMIN_USERS=admin@galaxy.org,test@bx.psu.edu \
|
||||
GALAXY_CONFIG_OVERRIDE_ALLOW_USER_DATASET_PURGE=true \
|
||||
GALAXY_CONFIG_OVERRIDE_ALLOW_LIBRARY_PATH_PASTE=true \
|
||||
GALAXY_CONFIG_OVERRIDE_ENABLE_BETA_WORKFLOW_MODULES=true \
|
||||
GALAXY_CONFIG_OVERRIDE_ALLOW_USER_DELETION=true \
|
||||
GALAXY_CONFIG_OVERRIDE_DATABASE_CONNECTION=postgresql://postgres@postgres/galaxy \
|
||||
GALAXY_CONFIG_OVERRIDE_MASTER_API_KEY=94a548bea347a35e457a804bf75bec53 \
|
||||
GALAXY_CONFIG_OVERRIDE_JOB_CONFIG_FILE=/galaxy/config/job_conf.xml.sample_basic \
|
||||
GALAXY_CONFIG_OVERRIDE_DATATYPES_CONFIG_FILE=/galaxy/test/functional/tools/sample_datatypes_conf.xml \
|
||||
GALAXY_CONFIG_OVERRIDE_TOOL_CONFIG_FILE=/galaxy/test/functional/tools/samples_tool_conf.xml \
|
||||
GALAXY_CONFIG_FILE=/galaxy/.ci/jenkins/selenium/galaxy.ini \
|
||||
GALAXY_VIRTUAL_ENV=/galaxy_env
|
||||
|
||||
ADD run_galaxy.bash /run_galaxy.bash
|
||||
EXPOSE 8080
|
||||
CMD /run_galaxy.bash
|
||||
@@ -1,21 +0,0 @@
|
||||
version: '2'
|
||||
services:
|
||||
postgres:
|
||||
image: postgres
|
||||
galaxy:
|
||||
build: .
|
||||
image: ubuntu
|
||||
volumes:
|
||||
- "${TARGET_ROOT}:${TARGET_PATH}"
|
||||
links:
|
||||
- postgres
|
||||
ports:
|
||||
- "${GALAXY_PORT}:8080"
|
||||
environment:
|
||||
GALAXY_TEST_UID: "${MY_UID}"
|
||||
selenium:
|
||||
image: selenium/standalone-chrome:3.5.2
|
||||
ports:
|
||||
- "${SELENIUM_PORT}:4444"
|
||||
links:
|
||||
- galaxy
|
||||
@@ -1,17 +0,0 @@
|
||||
[server:main]
|
||||
|
||||
use = egg:Paste#http
|
||||
port = 8080
|
||||
host = 0.0.0.0
|
||||
use_threadpool = True
|
||||
threadpool_kill_thread_limit = 10800
|
||||
|
||||
[filter:proxy-prefix]
|
||||
use = egg:PasteDeploy#prefix
|
||||
prefix = /galaxypf
|
||||
|
||||
[app:main]
|
||||
|
||||
paste.app_factory = galaxy.web.buildapp:app_factory
|
||||
|
||||
filter-with = proxy-prefix
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Same hacks to setup a Galaxy user as used in test/docker/base/run_test_wrapper.sh
|
||||
# We want to make sure Galaxy runs as the same user as the external user so the files have the correct permission.
|
||||
echo "Deleting galaxy user - it may not exist and this is fine."
|
||||
deluser galaxy | true
|
||||
|
||||
: ${GALAXY_TEST_UID:-"1"}
|
||||
|
||||
echo "Creating galaxy group with gid $GALAXY_TEST_UID - it may already exist and this is fine."
|
||||
groupadd -r galaxy -g "$GALAXY_TEST_UID" | true
|
||||
echo "Creating galaxy user with uid $GALAXY_TEST_UID - it may already exist and this is fine."
|
||||
useradd -u $GALAXY_TEST_UID -r -g galaxy -d /home/galaxy -c "Galaxy User" galaxy -s /bin/bash | true
|
||||
echo "Setting galaxy user password - the operation may fail."
|
||||
echo "galaxy:galaxy" | chpasswd | true
|
||||
|
||||
virtualenv "$GALAXY_VIRTUAL_ENV"
|
||||
chown -R "$GALAXY_TEST_UID:$GALAXY_TEST_UID" "$GALAXY_VIRTUAL_ENV"
|
||||
|
||||
cd /galaxy
|
||||
sudo -E -H -u "#${GALAXY_TEST_UID}" ./scripts/common_startup.sh || { echo "common_startup.sh failed"; exit 1; }
|
||||
|
||||
echo "Waiting for postgres to become available"
|
||||
while ! nc -z postgres 5432;
|
||||
do
|
||||
sleep 1
|
||||
printf "."
|
||||
done
|
||||
|
||||
echo "Creating postgres database for Galaxy"
|
||||
createdb -w -U postgres -h postgres galaxy
|
||||
|
||||
echo "Starting and waiting for Galaxy daemon(s)"
|
||||
sudo -E -H -u "#${GALAXY_TEST_UID}" GALAXY_RUN_ALL=1 bash "$GALAXY_ROOT/run.sh" --daemon --wait
|
||||
|
||||
echo "Galaxy daemon ready, monitoring Galaxy logs"
|
||||
tail -f "$GALAXY_ROOT/main.log"
|
||||
@@ -1,124 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
TEST_DIRECTORY=`dirname $0`
|
||||
|
||||
DEFAULT_COMPOSE_PROJECT_NAME=`basename $TEST_DIRECTORY`
|
||||
COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-$DEFAULT_COMPOSE_PROJECT_NAME}
|
||||
# If in Jenkins environment, append ${BUILD_NUMBER} to project so builds don't interfer.
|
||||
if [ ! -z "$BUILD_NUMBER" ];
|
||||
then
|
||||
COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME}${BUILD_NUMBER}"
|
||||
fi
|
||||
export COMPOSE_PROJECT_NAME
|
||||
|
||||
echo "Running Jenkins test from $TEST_DIRECTORY with compose project name $COMPOSE_PROJECT_NAME"
|
||||
|
||||
find lib -iname '*pyc' -exec rm -rf {} \;
|
||||
find test -iname '*pyc' -exec rm -rf {} \;
|
||||
|
||||
./scripts/common_startup.sh --dev-wheels
|
||||
|
||||
. .venv/bin/activate
|
||||
|
||||
pip install docker-compose
|
||||
|
||||
# TODO: Let docker-compose pick these at random.
|
||||
export GALAXY_PORT=`python -c 'from __future__ import print_function; import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'`
|
||||
export SELENIUM_PORT=`python -c 'from __future__ import print_function; import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'`
|
||||
|
||||
export TARGET_ROOT=`pwd`
|
||||
export TARGET_PATH=/galaxy
|
||||
export MY_UID=$(id -u)
|
||||
|
||||
cd $TEST_DIRECTORY
|
||||
|
||||
echo "Cleaning up previous executions if needed."
|
||||
docker-compose down | true
|
||||
docker-compose build galaxy
|
||||
docker-compose up -d
|
||||
|
||||
function tear_down {
|
||||
docker-compose down
|
||||
}
|
||||
|
||||
trap tear_down EXIT
|
||||
|
||||
for service_name in postgres galaxy selenium
|
||||
do
|
||||
echo "Waiting on service ${service_name}"
|
||||
while true
|
||||
do
|
||||
if docker ps | grep -q "${COMPOSE_PROJECT_NAME}_${service_name}"
|
||||
then
|
||||
container_id=`docker ps | grep "${COMPOSE_PROJECT_NAME}_${service_name}" | cut -d " " -f 1`
|
||||
eval "${service_name}_container_id=${container_id}"
|
||||
echo "Service ${service_name} ready - with container ID ${container_id}"
|
||||
break
|
||||
fi
|
||||
printf "."
|
||||
sleep 1;
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
if [ "$1" = "--debug-running-containers" ];
|
||||
then
|
||||
env
|
||||
exit 0
|
||||
fi
|
||||
|
||||
export GALAXY_TEST_EXTERNAL="http://localhost:$GALAXY_PORT/"
|
||||
|
||||
echo "Waiting on docker-compose managed Galaxy server - $GALAXY_TEST_EXTERNAL."
|
||||
while ! curl -s "$GALAXY_TEST_EXTERNAL";
|
||||
do
|
||||
for service_name in postgres galaxy selenium
|
||||
do
|
||||
if ! docker ps | grep -q "${COMPOSE_PROJECT_NAME}_${service_name}"
|
||||
then
|
||||
echo "Service ${service_name} stopped before Galaxy came up, exiting and halting containers."
|
||||
for service_name in postgres galaxy selenium
|
||||
do
|
||||
container_id_var="${service_name}_container_id"
|
||||
container_id="${!container_id_var}"
|
||||
echo "Dumping logs for $service_name container (${container_id})..."
|
||||
echo "---"
|
||||
docker logs "${container_id}"
|
||||
echo "---"
|
||||
done
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
printf "."
|
||||
sleep 4;
|
||||
done;
|
||||
|
||||
# Access Selenium on localhost via port $SELENIUM_PORT
|
||||
export GALAXY_TEST_SELENIUM_REMOTE=1
|
||||
export GALAXY_TEST_SELENIUM_REMOTE_PORT="${SELENIUM_PORT}"
|
||||
|
||||
# Retry all failed Selenium tests a second time to deal
|
||||
# with transiently failing tests. Failure information for
|
||||
# first tests is still populated in database/test_errors
|
||||
# and available at the top of the Jenkins test report.
|
||||
export GALAXY_TEST_SELENIUM_RETRIES=1
|
||||
|
||||
# Access Galaxy on localhost via port $GALAXY_PORT
|
||||
export GALAXY_TEST_PORT="${GALAXY_PORT}"
|
||||
|
||||
# Have Selenium access Galaxy at this URL
|
||||
export GALAXY_TEST_EXTERNAL_FROM_SELENIUM="http://galaxy:8080/galaxypf"
|
||||
export GALAXY_TEST_EXTERNAL="http://localhost:${GALAXY_TEST_PORT}/galaxypf"
|
||||
|
||||
# Point tests at the Master API Key configured in the Dockerfile.
|
||||
export GALAXY_CONFIG_MASTER_API_KEY=94a548bea347a35e457a804bf75bec53
|
||||
|
||||
cd ../../..
|
||||
|
||||
./run_tests.sh --selenium "$@"
|
||||
exit_code=$?
|
||||
|
||||
cd $TEST_DIRECTORY
|
||||
|
||||
exit $exit_code
|
||||
@@ -1 +0,0 @@
|
||||
selenium
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Enable retries on tests to reduce chances of transient failures.
|
||||
: ${GALAXY_TEST_SELENIUM_RETRIES:=1}
|
||||
|
||||
# If in Jenkins environment, use it for artifacts.
|
||||
if [ -n "$BUILD_NUMBER" ];
|
||||
then
|
||||
: ${GALAXY_TEST_ERRORS_DIRECTORY:=${BUILD_NUMBER}-test-errors}
|
||||
: ${GALAXY_TEST_SCREENSHOTS_DIRECTORY:=${BUILD_NUMBER}-test-screenshots}
|
||||
else
|
||||
: ${GALAXY_TEST_ERRORS_DIRECTORY:=database/test-errors}
|
||||
: ${GALAXY_TEST_SCREENSHOTS_DIRECTORY:=database/test-screenshots}
|
||||
fi
|
||||
|
||||
mkdir -p "$GALAXY_TEST_ERRORS_DIRECTORY"
|
||||
mkdir -p "$GALAXY_TEST_SCREENSHOTS_DIRECTORY"
|
||||
|
||||
mkdir -p ~/.jenkins-yarn-cache
|
||||
YARN_CACHE_FOLDER=~/.jenkins-yarn-cache
|
||||
|
||||
# Start Selenium server in the test Docker container.
|
||||
DOCKER_RUN_EXTRA_ARGS="${DOCKER_RUN_EXTRA_ARGS} --shm-size=2g -v $YARN_CACHE_FOLDER:$YARN_CACHE_FOLDER -e YARN_CACHE_FOLDER=$YARN_CACHE_FOLDER -e USE_SELENIUM=1 -e GALAXY_TEST_SELENIUM_RETRIES=${GALAXY_TEST_SELENIUM_RETRIES} -e GALAXY_TEST_ERRORS_DIRECTORY=${GALAXY_TEST_ERRORS_DIRECTORY} -e GALAXY_TEST_SCREENSHOTS_DIRECTORY=${GALAXY_TEST_SCREENSHOTS_DIRECTORY}"
|
||||
export DOCKER_RUN_EXTRA_ARGS
|
||||
|
||||
./run_tests.sh --dockerize --db postgres --clean_pyc --skip_flakey_fails --selenium "$@"
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
./run_tests.sh --dockerize --db postgres --clean_pyc --toolshed "$@"
|
||||
@@ -0,0 +1,32 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: testing
|
||||
name: testing
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: test
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: test
|
||||
spec:
|
||||
containers:
|
||||
- image: postgres:12
|
||||
name: postgres
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: postgres
|
||||
- name: POSTGRES_USER
|
||||
value: postgres
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: postgres
|
||||
- image: rabbitmq
|
||||
name: rabbitmq
|
||||
ports:
|
||||
- containerPort: 5672
|
||||
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ex
|
||||
|
||||
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
|
||||
kubectl apply -f "$SCRIPTDIR/deployment.yaml"
|
||||
kubectl expose deployment testing --type=LoadBalancer --name=testing-service
|
||||
|
||||
CLUSTER_IP=$(kubectl get service testing-service -o jsonpath='{.spec.clusterIP}')
|
||||
GALAXY_TEST_DBURI="postgresql://postgres:postgres@${CLUSTER_IP}:5432/galaxy?client_encoding=utf-8"
|
||||
GALAXY_TEST_AMQP_URL="amqp://${CLUSTER_IP}:5672//"
|
||||
export GALAXY_TEST_DBURI
|
||||
export GALAXY_TEST_AMQP_URL
|
||||
+7
-63
@@ -17,6 +17,8 @@ variables:
|
||||
- ~/.cache/yarn
|
||||
install_tox: &install_tox
|
||||
run: sudo pip install tox
|
||||
install_deb_reqs: &install_deb_reqs
|
||||
run: sudo apt-get update && sudo apt-get install ffmpeg nodejs -y
|
||||
set_workdir: &set_workdir
|
||||
working_directory: ~/repo
|
||||
requires_get_code: &requires_get_code
|
||||
@@ -25,7 +27,7 @@ variables:
|
||||
jobs:
|
||||
get_code:
|
||||
docker:
|
||||
- image: circleci/python:3.5
|
||||
- image: circleci/python:3.7
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
# Replace standard code checkout with shallow clone to speed things up.
|
||||
@@ -81,44 +83,9 @@ jobs:
|
||||
key: v1-repo-{{ .Environment.CIRCLE_SHA1 }}
|
||||
paths:
|
||||
- ~/repo
|
||||
py35_docstring:
|
||||
docker:
|
||||
- image: circleci/python:3.5
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_repo_cache
|
||||
- *install_tox
|
||||
- run: tox -e py35-lint_docstring_include_list
|
||||
py35_lint:
|
||||
docker:
|
||||
- image: circleci/python:3.5
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_repo_cache
|
||||
- *install_tox
|
||||
- run: tox -e py35-lint
|
||||
py35_unit:
|
||||
docker:
|
||||
- image: circleci/python:3.5
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_repo_cache
|
||||
- *install_tox
|
||||
- run: tox -e py35-unit
|
||||
py35_first_startup:
|
||||
docker:
|
||||
- image: circleci/python:3.5
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_repo_cache
|
||||
# Use this job to test the latest migrations
|
||||
- run: wget -q https://github.com/jmchilton/galaxy-downloads/raw/master/db_gx_rev_0141.sqlite
|
||||
- run: mv db_gx_rev_0141.sqlite database/universe.sqlite
|
||||
- *install_tox
|
||||
- run: tox -e py35-first_startup
|
||||
validate_test_tools:
|
||||
docker:
|
||||
- image: circleci/python:3.5
|
||||
- image: circleci/python:3.7
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_repo_cache
|
||||
@@ -128,29 +95,16 @@ jobs:
|
||||
- run: tox -e validate_test_tools
|
||||
test_galaxy_packages:
|
||||
docker:
|
||||
- image: circleci/python:3.5
|
||||
- image: circleci/python:3.7
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_repo_cache
|
||||
- *install_tox
|
||||
- *install_deb_reqs
|
||||
- run: tox -e test_galaxy_packages
|
||||
js_unit:
|
||||
docker:
|
||||
- image: circleci/node:12-browsers
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_yarn_cache
|
||||
- run: cd client && yarn install --frozen-lockfile
|
||||
- *save_yarn_cache
|
||||
- run:
|
||||
name: Build client
|
||||
command: cd client && yarn run build
|
||||
environment:
|
||||
NODE_OPTIONS: --max_old_space_size=4096
|
||||
- run: cd client && yarn run test
|
||||
js_lint:
|
||||
docker:
|
||||
- image: circleci/node:12-browsers
|
||||
- image: cimg/node:16.13.2
|
||||
<<: *set_workdir
|
||||
steps:
|
||||
- *restore_yarn_cache
|
||||
@@ -163,19 +117,9 @@ workflows:
|
||||
get_code_and_test:
|
||||
jobs:
|
||||
- get_code
|
||||
- py35_docstring:
|
||||
<<: *requires_get_code
|
||||
- py35_lint:
|
||||
<<: *requires_get_code
|
||||
- py35_unit:
|
||||
<<: *requires_get_code
|
||||
- py35_first_startup:
|
||||
<<: *requires_get_code
|
||||
- test_galaxy_packages:
|
||||
<<: *requires_get_code
|
||||
- validate_test_tools:
|
||||
<<: *requires_get_code
|
||||
- js_unit:
|
||||
<<: *requires_get_code
|
||||
- js_lint:
|
||||
<<: *requires_get_code
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
.k8s_ci.Dockerfile
|
||||
.venv
|
||||
database
|
||||
node_modules
|
||||
@@ -0,0 +1,7 @@
|
||||
# Migrate code style to Black and Apply isort
|
||||
623a5e165ad79e15321b19b2a2afbf2f9224cc90
|
||||
# Application of black styling to /tools/
|
||||
03351d2a9f81b938d650e2a955c65c18526ee7f0
|
||||
# Migrate code style to Prettier
|
||||
5b2928f851bd5ea3b9c2a04abf2cee9ff0bc54cc
|
||||
87873c5e2f4e6b97fe0f2084bfca0295fcd471de
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Galaxy Version and/or server at which you observed the bug**
|
||||
Galaxy Version: (check <galaxy_url>/api/version if you don't know)
|
||||
Commit: (run `git rev-parse HEAD` if you run this Galaxy server)
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1 @@
|
||||
comment: false
|
||||
@@ -0,0 +1,68 @@
|
||||
---
|
||||
area/admin:
|
||||
- client/src/components/admin/**/*
|
||||
- doc/source/admin/**/*
|
||||
area/API:
|
||||
- lib/galaxy/webapps/galaxy/api/**/*
|
||||
area/client:
|
||||
- client/*
|
||||
area/datatypes:
|
||||
- lib/galaxy/datatypes/**/*
|
||||
- lib/galaxy/config/sample/datatypes_conf.xml.sample
|
||||
area/dependencies:
|
||||
- lib/galaxy/dependencies/**/*
|
||||
area/documentation:
|
||||
- doc/**/*
|
||||
area/jobs:
|
||||
- lib/galaxy/jobs/**/*
|
||||
area/libraries:
|
||||
- client/src/components/LibraryFolder/**/*
|
||||
- lib/galaxy/webapps/galaxy/api/libraries.py
|
||||
area/objectstore:
|
||||
- lib/galaxy/objectstore/**/*
|
||||
area/packaging:
|
||||
- packages/**/*
|
||||
area/reports:
|
||||
- client/src/reports/**/*
|
||||
- lib/galaxy/webapps/reports/**/*
|
||||
- templates/webapps/reports/**/*
|
||||
area/scripts:
|
||||
- scripts/**/*
|
||||
area/security:
|
||||
- lib/galaxy/security/**/*
|
||||
area/testing:
|
||||
- lib/galaxy_test/**/*
|
||||
- run_tests.sh
|
||||
- test/**/*
|
||||
- test-data/**/*
|
||||
area/testing/api:
|
||||
- lib/galaxy_test/api/**/*
|
||||
area/testing/integration:
|
||||
- test/integration/**/*
|
||||
- test/integration_selenium/**/*
|
||||
area/testing/selenium:
|
||||
- lib/galaxy/selenium/**/*
|
||||
- lib/galaxy_test/selenium/**/*
|
||||
area/tool-dependencies:
|
||||
- lib/galaxy/tool_util/deps/**/*
|
||||
area/tool-framework:
|
||||
- lib/galaxy/tools/**/*
|
||||
- lib/galaxy/tool_util/**/*
|
||||
- lib/galaxy/webapps/galaxy/api/tools.py
|
||||
area/tools:
|
||||
- tools/**/*
|
||||
- tool-data/**/*
|
||||
area/toolshed:
|
||||
- client/src/toolshed/**/*
|
||||
- lib/galaxy/webapps/galaxy/api/toolshed.py
|
||||
- lib/toolshed/**/*
|
||||
- templates/webapps/tool_shed/**/*
|
||||
area/UI-UX:
|
||||
- client/src/**/*
|
||||
- templates/**/*
|
||||
area/util:
|
||||
- lib/galaxy/util/**/*
|
||||
area/visualizations:
|
||||
- config/plugins/visualizations/**/*
|
||||
area/workflows:
|
||||
- lib/galaxy/workflow/**/*
|
||||
@@ -0,0 +1,14 @@
|
||||
(Please replace this header with a description of your pull request. Please include *BOTH* what you did and why you made the changes. The "why" may simply be citing a relevant Galaxy issue.)
|
||||
(If fixing a bug, please add any relevant error or traceback)
|
||||
(For UI components, it is recommended to include screenshots or screencasts)
|
||||
|
||||
## How to test the changes?
|
||||
(Select all options that apply)
|
||||
- [ ] I've included appropriate [automated tests](https://docs.galaxyproject.org/en/latest/dev/writing_tests.html).
|
||||
- [ ] This is a refactoring of components with existing test coverage.
|
||||
- [ ] Instructions for manual testing are as follows:
|
||||
1. [add testing steps and prerequisites here if you didn't write automated tests covering all your changes]
|
||||
|
||||
## License
|
||||
- [x] I agree to license these contributions under [Galaxy's current license](https://github.com/galaxyproject/galaxy/blob/dev/LICENSE.txt).
|
||||
- [x] I agree to allow the Galaxy committers to license these and all my past contributions to the core galaxy codebase under the [MIT license](https://opensource.org/licenses/MIT). If this condition is an issue, uncheck and just let us know why with an e-mail to galaxy-committers@lists.galaxyproject.org.
|
||||
@@ -0,0 +1,76 @@
|
||||
name: API tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_DEPENDENCIES_INSTALL_WEASYPRINT: '1'
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_RAISE_EXCEPTION_ON_HISTORYLESS_HDA: '1'
|
||||
GALAXY_CONFIG_SQLALCHEMY_WARN_20: '1'
|
||||
concurrency:
|
||||
group: api-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-api
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --coverage --skip_flakey_fails -api
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: api
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: API test results (${{ matrix.python-version }})
|
||||
path: 'galaxy root/run_api_tests.html'
|
||||
@@ -0,0 +1,50 @@
|
||||
name: Build Container Image
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'release*'
|
||||
- dev
|
||||
concurrency:
|
||||
group: docker-build-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build:
|
||||
name: Build container image
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'galaxyproject'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# https://stackoverflow.com/questions/59810838/how-to-get-the-short-sha-for-the-github-workflow
|
||||
- name: Set outputs
|
||||
id: commit
|
||||
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
|
||||
- name: Set branch name
|
||||
id: branch
|
||||
run: echo "::set-output name=name::$(BRANCH_NAME=${GITHUB_REF##*/}; echo ${BRANCH_NAME/release_/})"
|
||||
- name: Build container image
|
||||
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 galaxyproject/galaxy-min:${{ steps.branch.outputs.name }} -t quay.io/galaxyproject/galaxy-min:${{ steps.branch.outputs.name }} -f .k8s_ci.Dockerfile
|
||||
- name: Create auto-expiring one for per-commit auto repository
|
||||
run: echo "FROM galaxyproject/galaxy-min:${{ steps.branch.outputs.name }}" | docker build --label "quay.expires-after"="90d" -t "quay.io/galaxyproject/galaxy-k8s-auto:${{ steps.commit.outputs.sha_short }}" -
|
||||
- name: Login to quay.io
|
||||
uses: actions-hub/docker/login@master
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.QUAY_USERNAME }}
|
||||
DOCKER_PASSWORD: ${{ secrets.QUAY_PASSWORD }}
|
||||
DOCKER_REGISTRY_URL: quay.io
|
||||
- name: Push to quay.io with branch name
|
||||
uses: actions-hub/docker@master
|
||||
with:
|
||||
args: push quay.io/galaxyproject/galaxy-min:${{ steps.branch.outputs.name }}
|
||||
- name: Push to quay.io with commit hash
|
||||
uses: actions-hub/docker@master
|
||||
with:
|
||||
args: push quay.io/galaxyproject/galaxy-k8s-auto:${{ steps.commit.outputs.sha_short }}
|
||||
- name: Login to DockerHub
|
||||
uses: actions-hub/docker/login@master
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
- name: Push to DockerHub with branch name
|
||||
uses: actions-hub/docker@master
|
||||
with:
|
||||
args: push galaxyproject/galaxy-min:${{ steps.branch.outputs.name }}
|
||||
@@ -0,0 +1,70 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ dev ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ dev ]
|
||||
schedule:
|
||||
- cron: '16 6 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ['javascript', 'python']
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
@@ -1,14 +1,33 @@
|
||||
name: Converter tests
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_TEST_RAISE_EXCEPTION_ON_HISTORYLESS_HDA: '1'
|
||||
concurrency:
|
||||
group: converter-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: ['3.7']
|
||||
steps:
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
@@ -30,5 +49,37 @@ jobs:
|
||||
run: rsync -av --remove-source-files --exclude .git galaxy-test-data/ 'galaxy root/test-data/'
|
||||
- name: Install planemo
|
||||
run: pip install planemo
|
||||
- name: Install jq
|
||||
run: sudo apt-get install jq
|
||||
- name: Determine converters to check
|
||||
run: |
|
||||
ls 'galaxy root'/lib/galaxy/datatypes/converters/*xml | grep -v -f 'galaxy root'/lib/galaxy/datatypes/converters/.tt_skip > tool_list.txt
|
||||
echo "Skipping checks for the following converters:"
|
||||
ls 'galaxy root'/lib/galaxy/datatypes/converters/*xml | grep -f 'galaxy root'/lib/galaxy/datatypes/converters/.tt_skip
|
||||
echo "Checking only the following converters:"
|
||||
cat tool_list.txt
|
||||
- name: Lint converters
|
||||
run: |
|
||||
mapfile -t TOOL_ARRAY < tool_list.txt
|
||||
for CONVERTER in "${TOOL_ARRAY[@]}"; do
|
||||
planemo lint --skip citations,stdio,help --report_level warn "$CONVERTER"
|
||||
done
|
||||
- name: Run tests
|
||||
run: planemo test --galaxy_python_version ${{ matrix.python-version }} --galaxy_root 'galaxy root' 'galaxy root'/lib/galaxy/datatypes/converters/*xml
|
||||
run: |
|
||||
mkdir -p json_output
|
||||
mapfile -t TOOL_ARRAY < tool_list.txt
|
||||
for CONVERTER in "${TOOL_ARRAY[@]}"; do
|
||||
json=$(mktemp -u -p json_output --suff .json)
|
||||
planemo test --test_output_json "$json" --galaxy_python_version ${{ matrix.python-version }} --galaxy_root 'galaxy root' "$CONVERTER" || true
|
||||
done
|
||||
planemo merge_test_reports json_output/*.json tool_test_output.json
|
||||
planemo test_reports tool_test_output.json --test_output tool_test_output.html
|
||||
if jq '.["tests"][]["data"]["status"]' tool_test_output.json | grep -v "success"; then
|
||||
echo "Unsuccessful tests found, inspect the 'Converter test results' artifact for details."
|
||||
exit 1
|
||||
fi
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Converter test results (${{ matrix.python-version }})
|
||||
path: tool_test_output.html
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
name: CWL conformance
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
concurrency:
|
||||
group: cwl-conformance-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
if: ${{ false }}
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: ${{ startsWith(matrix.marker, 'red') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
marker: ['green', 'red and required', 'red and not required']
|
||||
conformance-version: ['cwl_conformance_v1_0'] #, 'cwl_conformance_v1_1', 'cwl_conformance_v1_2']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --coverage --skip_flakey_fails -cwl lib/galaxy_test/api/cwl -- -m "${{ matrix.marker }} and ${{ matrix.conformance-version }}"
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: cwl-conformance
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: CWL conformance test results (${{ matrix.python-version }}, ${{ matrix.marker }}, ${{ matrix.conformance-version }})
|
||||
path: 'galaxy root/run_cwl_tests.html'
|
||||
@@ -0,0 +1,71 @@
|
||||
name: Database indexes
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
concurrency:
|
||||
group: database-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
defaults:
|
||||
run:
|
||||
working-directory: 'galaxy root'
|
||||
jobs:
|
||||
check:
|
||||
name: Check database indexes
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
db: ['postgresql', 'sqlite']
|
||||
postgresql-version: ['13']
|
||||
include:
|
||||
- db: postgresql
|
||||
postgresql-version: '9.6'
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:${{ matrix.postgresql-version }}
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache tox env
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .tox
|
||||
key: tox-cache-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-check-indexes
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
- name: Check indexes on postgresql
|
||||
if: matrix.db == 'postgresql'
|
||||
env:
|
||||
GALAXY_CONFIG_OVERRIDE_DATABASE_CONNECTION: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
run: tox -e check_indexes
|
||||
- name: Check indexes on sqlite
|
||||
if: matrix.db == 'sqlite'
|
||||
run: tox -e check_indexes
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Update dependencies
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 3 * * 6' # Run every saturday at 3 am.
|
||||
jobs:
|
||||
update_dependencies:
|
||||
name: Update dependencies
|
||||
if: github.repository_owner == 'galaxyproject'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}
|
||||
- name: Update dependencies
|
||||
run: |
|
||||
python -m venv .venv
|
||||
make update-dependencies
|
||||
- name: Create pull request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
author: galaxybot <galaxybot@users.noreply.github.com>
|
||||
token: ${{ secrets.GALAXYBOT_PAT }}
|
||||
commit-message: Update Python dependencies
|
||||
branch: dev_auto_update_dependencies
|
||||
delete-branch: true
|
||||
push-to-fork: galaxybot/galaxy
|
||||
title: Update Python dependencies
|
||||
body: Run `make update-dependencies`.
|
||||
labels: area/dependencies
|
||||
@@ -0,0 +1,77 @@
|
||||
name: Build docs
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
concurrency:
|
||||
group: docs-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
steps:
|
||||
- name: Get target branch name (push)
|
||||
if: github.event_name == 'push'
|
||||
run: echo "TARGET_BRANCH=${GITHUB_REF##*/}" >> $GITHUB_ENV
|
||||
- name: Get target branch name (pull request)
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo "TARGET_BRANCH=$GITHUB_BASE_REF" >> $GITHUB_ENV
|
||||
- name: Show target branch name
|
||||
run: echo $TARGET_BRANCH
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('requirements.txt') }}
|
||||
- name: Install Python dependencies
|
||||
run: pip install -r requirements.txt -r lib/galaxy/dependencies/dev-requirements.txt sphinxcontrib-simpleversioning
|
||||
- name: Add Google Analytics to doc/source/conf.py
|
||||
run: |
|
||||
sed -i -e "/html_theme_options = {/a\
|
||||
\ 'analytics_id': 'UA-45719423-17'," -e "s#https://docs.galaxyproject.org/en/[^/]*/#https://docs.galaxyproject.org/en/$TARGET_BRANCH/#" doc/source/conf.py
|
||||
- name: Checkout the latest doc/source/conf.versioning.py
|
||||
if: github.event_name != 'push' || github.ref != 'refs/heads/dev'
|
||||
run: |
|
||||
# We cannot just download the latest version from dev, because it may be newer in this branch/PR
|
||||
git fetch origin dev:dev
|
||||
if [ ! -f doc/source/conf.versioning.py ] || [ "$(git log -1 --pretty="format:%ct" dev -- doc/source/conf.versioning.py)" -gt "$(git log -1 --pretty="format:%ct" -- doc/source/conf.versioning.py)" ]; then
|
||||
git checkout dev -- doc/source/conf.versioning.py
|
||||
fi
|
||||
- name: Append doc/source/conf.versioning.py
|
||||
run: cat doc/source/conf.versioning.py >> doc/source/conf.py
|
||||
- name: Build docs
|
||||
run: make docs
|
||||
- name: Deploy docs
|
||||
if: github.event_name == 'push' && github.repository_owner == 'galaxyproject'
|
||||
env:
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
run: |
|
||||
case "$TARGET_BRANCH" in
|
||||
release_[[:digit:]][[:digit:]].[[:digit:]][[:digit:]]|master)
|
||||
UPLOAD_DIR=$TARGET_BRANCH
|
||||
;;
|
||||
dev)
|
||||
UPLOAD_DIR=latest
|
||||
;;
|
||||
*)
|
||||
echo "Not deploying documentation for branch $TARGET_BRANCH"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
pip install awscli
|
||||
aws s3 sync doc/build/html/ "s3://galaxy-docs/en/$UPLOAD_DIR" --region us-east-2 --size-only --delete
|
||||
@@ -0,0 +1,58 @@
|
||||
name: first startup
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
env:
|
||||
YARN_INSTALL_OPTS: --frozen-lockfile
|
||||
concurrency:
|
||||
group: first-startup-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
|
||||
test:
|
||||
name: Startup test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.7', '3.10']
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -l {0}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache tox env
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .tox
|
||||
key: tox-cache-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-first-startup
|
||||
- uses: mvdbeek/gha-yarn-cache@master
|
||||
with:
|
||||
yarn-lock-file: 'galaxy root/client/yarn.lock'
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
- name: run tests
|
||||
run: tox -e first_startup
|
||||
working-directory: 'galaxy root'
|
||||
@@ -0,0 +1,74 @@
|
||||
name: Framework tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_RAISE_EXCEPTION_ON_HISTORYLESS_HDA: '1'
|
||||
concurrency:
|
||||
group: framework-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-framework
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --coverage --framework
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: framework
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Framework test results (${{ matrix.python-version }})
|
||||
path: 'galaxy root/run_framework_tests.html'
|
||||
@@ -1,19 +1,38 @@
|
||||
name: Integration
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgres://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_AMQP_URL: 'amqp://localhost:5672//'
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_RAISE_EXCEPTION_ON_HISTORYLESS_HDA: '1'
|
||||
GALAXY_CONFIG_SQLALCHEMY_WARN_20: '1'
|
||||
concurrency:
|
||||
group: integration-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
subset: ['upload_datatype', 'extended_metadata', 'kubernetes', 'not (upload_datatype or extended_metadata or kubernetes)']
|
||||
python-version: ['3.7']
|
||||
chunk: ['0', '1', '2', '3']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:11
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
@@ -25,36 +44,59 @@ jobs:
|
||||
ports:
|
||||
- 5672:5672
|
||||
steps:
|
||||
- name: Prune unused docker image, volumes and containers
|
||||
run: docker system prune -a -f
|
||||
- name: Clean dotnet folder for space
|
||||
if: matrix.subset == 'kubernetes'
|
||||
run: rm -Rf /usr/share/dotnet
|
||||
- name: Setup Minikube
|
||||
if: matrix.subset == 'kubernetes'
|
||||
id: minikube
|
||||
uses: CodingNagger/minikube-setup-action@v1.0.3
|
||||
with:
|
||||
minikube-version: "1.9.0-0_amd64"
|
||||
- name: Launch Minikube
|
||||
if: matrix.subset == 'kubernetes'
|
||||
run: eval ${{ steps.minikube.outputs.launcher }}
|
||||
- name: Check pods
|
||||
if: matrix.subset == 'kubernetes'
|
||||
run: |
|
||||
kubectl get pods
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Run tests
|
||||
run: './run_tests.sh -integration test/integration -- -k "${{ matrix.subset }}"'
|
||||
working-directory: 'galaxy root'
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
# Skip outputs_to_working_directory: true in integration tests, doesn't work with pulsar
|
||||
# echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- name: Prune unused docker image, volumes and containers
|
||||
run: docker system prune -a -f
|
||||
- name: Clean dotnet folder for space
|
||||
run: rm -Rf /usr/share/dotnet
|
||||
- name: Setup Minikube
|
||||
id: minikube
|
||||
uses: CodingNagger/minikube-setup-action@v1.0.3
|
||||
with:
|
||||
minikube-version: "1.9.0-0_amd64"
|
||||
- name: Launch Minikube
|
||||
run: eval ${{ steps.minikube.outputs.launcher }}
|
||||
- name: Check pods
|
||||
run: |
|
||||
kubectl get pods
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-integration
|
||||
- name: Install ffmpeg
|
||||
run: sudo apt-get update && sudo apt-get -y install ffmpeg
|
||||
- name: Run tests
|
||||
run: |
|
||||
. .ci/minikube-test-setup/start_services.sh
|
||||
./run_tests.sh --coverage -integration test/integration -- --num-shards=4 --shard-id=${{ matrix.chunk }}
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: integration
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Integration test results (${{ matrix.python-version }}, ${{ matrix.chunk }})
|
||||
path: 'galaxy root/run_integration_tests.html'
|
||||
|
||||
@@ -1,45 +1,86 @@
|
||||
name: Integration Selenium
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgres://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_SELENIUM_REMOTE: '1'
|
||||
GALAXY_TEST_SELENIUM_REMOTE_PORT: "4444"
|
||||
GALAXY_SKIP_CLIENT_BUILD: '0'
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_RAISE_EXCEPTION_ON_HISTORYLESS_HDA: '1'
|
||||
GALAXY_TEST_SELENIUM_RETRIES: 1
|
||||
YARN_INSTALL_OPTS: --frozen-lockfile
|
||||
GALAXY_CONFIG_SQLALCHEMY_WARN_20: '1'
|
||||
GALAXY_DEPENDENCIES_INSTALL_WEASYPRINT: '1'
|
||||
concurrency:
|
||||
group: integration-selenium-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: ['3.7']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:11
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
selenium:
|
||||
image: selenium/standalone-chrome:3.141.59
|
||||
ports:
|
||||
- 4444:4444
|
||||
steps:
|
||||
- name: Prune unused docker image, volumes and containers
|
||||
run: docker system prune -a -f
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Run tests
|
||||
run: './run_tests.sh -integration test/integration_selenium'
|
||||
working-directory: 'galaxy root'
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- name: Prune unused docker image, volumes and containers
|
||||
run: docker system prune -a -f
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-integration-selenium
|
||||
- uses: mvdbeek/gha-yarn-cache@master
|
||||
with:
|
||||
yarn-lock-file: 'galaxy root/client/yarn.lock'
|
||||
- uses: nanasess/setup-chromedriver@master
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --coverage -integration test/integration_selenium
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: integration-selenium
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Integration Selenium test results (${{ matrix.python-version }})
|
||||
path: 'galaxy root/run_integration_tests.html'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Integration Selenium debug info (${{ matrix.python-version }})
|
||||
path: 'galaxy root/database/test_errors'
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Client Unit Testing
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'client/**'
|
||||
- '.github/workflows/jest.yaml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'client/**'
|
||||
- '.github/workflows/jest.yaml'
|
||||
concurrency:
|
||||
group: client-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
client-unit-test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
node: [16]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node}}
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: 'client/yarn.lock'
|
||||
- run: yarn install --frozen-lockfile
|
||||
working-directory: client
|
||||
- name: Stage client libs (Gulp)
|
||||
run: yarn run gulp client
|
||||
working-directory: client
|
||||
- name: Run Unit Tests
|
||||
run: yarn run qunit
|
||||
working-directory: client
|
||||
- run: yarn jest
|
||||
working-directory: client
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Labels Verifier
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [closed]
|
||||
jobs:
|
||||
onMerged:
|
||||
name: "Check Labels on merge"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check Labels on merge
|
||||
if: |
|
||||
github.event.pull_request.merged == true &&
|
||||
! contains(join(github.event.pull_request.labels.*.name, ', '), 'kind/') &&
|
||||
! contains(github.event.pull_request.labels.*.name, 'merge') &&
|
||||
! contains(github.event.pull_request.labels.*.name, 'minor')
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
github.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: 'This PR was merged without a "kind/" label, please correct.',
|
||||
})
|
||||
@@ -0,0 +1,47 @@
|
||||
name: Python linting
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.py'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.py'
|
||||
concurrency:
|
||||
group: py-lint-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7', '3.10']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('lib/galaxy/dependencies/pinned-lint-requirements.txt') }}
|
||||
- name: Cache tox env
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .tox
|
||||
key: tox-cache-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('lib/galaxy/dependencies/pinned-lint-requirements.txt') }}-lint
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
- name: Run linting
|
||||
run: tox -e lint
|
||||
- name: Run docstring linting
|
||||
run: tox -e lint_docstring_include_list
|
||||
- name: Run mypy checks
|
||||
run: tox -e mypy
|
||||
- uses: psf/black@stable
|
||||
- uses: jamescurtin/isort-action@master
|
||||
@@ -0,0 +1,47 @@
|
||||
name: Maintenance Bot
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, edited, ready_for_review, unlabeled]
|
||||
jobs:
|
||||
labeler:
|
||||
name: Assign labels and milestone
|
||||
if: github.repository_owner == 'galaxyproject'
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MILESTONE_NUMBER: 22
|
||||
steps:
|
||||
- name: Get latest pull request labels
|
||||
id: get_pr_labels
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const response = await github.issues.listLabelsOnIssue({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
});
|
||||
console.log(response);
|
||||
return response.data;
|
||||
- name: Add area labels
|
||||
if: ${{ ! contains(join(fromJSON(steps.get_pr_labels.outputs.result).*.name, ', '), 'area/') }}
|
||||
uses: actions/labeler@main
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Assign milestone
|
||||
if: |
|
||||
! github.event.pull_request.milestone &&
|
||||
! contains(github.event.pull_request.labels.*.name, 'merge') &&
|
||||
! contains(github.event.pull_request.labels.*.name, 'status/WIP') &&
|
||||
! contains(github.event.pull_request.title, 'WIP') &&
|
||||
! github.event.pull_request.draft
|
||||
uses: actions/github-script@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
github.issues.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
milestone: ${{ env.MILESTONE_NUMBER }},
|
||||
});
|
||||
@@ -1,28 +1,54 @@
|
||||
name: Mulled Unit Tests
|
||||
on: [push, pull_request]
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
concurrency:
|
||||
group: mulled-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: ['3.7']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
- name: run tests
|
||||
run: tox -e mulled
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache tox env
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .tox
|
||||
key: tox-cache-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-mulled
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
- name: run tests
|
||||
run: tox -e mulled
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Mulled unit test results (${{ matrix.python-version }})
|
||||
path: 'galaxy root/run_unit_tests.html'
|
||||
|
||||
@@ -1,28 +1,49 @@
|
||||
name: OSX
|
||||
on: [push, pull_request]
|
||||
name: macOS startup
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
concurrency:
|
||||
group: osx-first-startup-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
|
||||
test:
|
||||
name: Startup test
|
||||
runs-on: macos-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -l {0}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/Library/Caches/pip
|
||||
# scripts/common_startup.sh creates a conda env for Galaxy containing Python 3.6
|
||||
key: pip-cache-3.6-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
# scripts/common_startup.sh creates a conda env for Galaxy containing Python 3.7
|
||||
key: pip-cache-3.7-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache tox env
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: .tox
|
||||
key: tox-cache-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-osx
|
||||
- name: Install and activate miniconda # use this job to test using Python from a conda environment
|
||||
uses: goanpeca/setup-miniconda@v1
|
||||
uses: conda-incubator/setup-miniconda@v2
|
||||
with:
|
||||
activate-environment: ''
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
- name: run tests
|
||||
run: tox -e first_startup
|
||||
shell: bash -l {0} # need this to have CONDA_EXE set
|
||||
working-directory: 'galaxy root'
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
name: Performance tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
concurrency:
|
||||
group: performance-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-performance
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --ci_test_metrics --structured_data_html --structured_data_report_file "test.json" --skip_flakey_fails -api lib/galaxy_test/performance
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: API test results
|
||||
path: 'galaxy root/run_api_tests.html'
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Performance Metrics
|
||||
path: 'galaxy root/test.html'
|
||||
@@ -0,0 +1,55 @@
|
||||
name: Reports startup
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
env:
|
||||
YARN_INSTALL_OPTS: --frozen-lockfile
|
||||
concurrency:
|
||||
group: reports-startup-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Reports startup test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.7', '3.10']
|
||||
defaults:
|
||||
run:
|
||||
shell: bash -l {0}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-reports-startup
|
||||
- uses: mvdbeek/gha-yarn-cache@master
|
||||
with:
|
||||
yarn-lock-file: 'galaxy root/client/yarn.lock'
|
||||
- name: Install tox
|
||||
run: pip install tox
|
||||
- name: Run tests
|
||||
run: tox -e reports_startup
|
||||
working-directory: 'galaxy root'
|
||||
@@ -0,0 +1,86 @@
|
||||
name: Selenium tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_CONFIG_GALAXY_URL_PREFIX: '/galaxypf'
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_RAISE_EXCEPTION_ON_HISTORYLESS_HDA: '1'
|
||||
GALAXY_TEST_SELENIUM_RETRIES: 1
|
||||
GALAXY_TEST_SKIP_FLAKEY_TESTS_ON_ERROR: 1
|
||||
YARN_INSTALL_OPTS: --frozen-lockfile
|
||||
GALAXY_CONFIG_SQLALCHEMY_WARN_20: '1'
|
||||
concurrency:
|
||||
group: selenium-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
chunk: [0, 1, 2]
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-selenium
|
||||
- uses: mvdbeek/gha-yarn-cache@master
|
||||
with:
|
||||
yarn-lock-file: 'galaxy root/client/yarn.lock'
|
||||
- uses: nanasess/setup-chromedriver@master
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --coverage -selenium lib/galaxy_test/selenium -- --num-shards=3 --shard-id=${{ matrix.chunk }}
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: selenium
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Selenium test results (${{ matrix.python-version }}, ${{ matrix.chunk }})
|
||||
path: 'galaxy root/run_selenium_tests.html'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Selenium debug info (${{ matrix.python-version }}, ${{ matrix.chunk }})
|
||||
path: 'galaxy root/database/test_errors'
|
||||
@@ -0,0 +1,87 @@
|
||||
name: Selenium tests (beta history panel)
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
schedule:
|
||||
# Run at midnight UTC every Tuesday
|
||||
- cron: '0 0 * * 2'
|
||||
env:
|
||||
GALAXY_CONFIG_GALAXY_URL_PREFIX: '/galaxypf'
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
GALAXY_TEST_RAISE_EXCEPTION_ON_HISTORYLESS_HDA: '1'
|
||||
GALAXY_TEST_SELENIUM_RETRIES: 1
|
||||
GALAXY_TEST_SELENIUM_BETA_HISTORY: 1
|
||||
GALAXY_TEST_SKIP_FLAKEY_TESTS_ON_ERROR: 1
|
||||
YARN_INSTALL_OPTS: --frozen-lockfile
|
||||
GALAXY_CONFIG_SQLALCHEMY_WARN_20: '1'
|
||||
concurrency:
|
||||
group: selenium-beta-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
chunk: [0, 1, 2]
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- if: github.event_name == 'schedule'
|
||||
run: |
|
||||
echo "GALAXY_CONFIG_OVERRIDE_METADATA_STRATEGY=extended" >> $GITHUB_ENV
|
||||
echo "GALAXY_CONFIG_OVERRIDE_OUTPUTS_TO_WORKING_DIRECTORY=true" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-selenium-beta
|
||||
- uses: mvdbeek/gha-yarn-cache@master
|
||||
with:
|
||||
yarn-lock-file: 'galaxy root/client/yarn.lock'
|
||||
- uses: nanasess/setup-chromedriver@master
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --coverage -selenium lib/galaxy_test/selenium -- --num-shards=3 --shard-id=${{ matrix.chunk }}
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: selenium-beta-history
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Selenium beta history panel test results (${{ matrix.python-version }}, ${{ matrix.chunk }})
|
||||
path: 'galaxy root/run_selenium_tests.html'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Selenium beta history panel debug info (${{ matrix.python-version }}, ${{ matrix.chunk }})
|
||||
path: 'galaxy root/database/test_errors'
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Test Galaxy release script
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- lib/galaxy/version.py
|
||||
- scripts/release.sh
|
||||
- test/release.sh
|
||||
pull_request:
|
||||
paths:
|
||||
- lib/galaxy/version.py
|
||||
- scripts/release.sh
|
||||
- test/release.sh
|
||||
concurrency:
|
||||
group: test-galaxy-release-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run tests
|
||||
run: ./test/release.sh
|
||||
@@ -1,18 +1,29 @@
|
||||
name: Toolshed
|
||||
on: [push, pull_request]
|
||||
name: Toolshed tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgres://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
TOOL_SHED_TEST_DBURI: 'postgres://postgres:postgres@localhost:5432/toolshed?client_encoding=utf8'
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/galaxy?client_encoding=utf8'
|
||||
TOOL_SHED_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/toolshed?client_encoding=utf8'
|
||||
concurrency:
|
||||
group: toolshed-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-18.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: ['3.7']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:11
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
@@ -20,18 +31,32 @@ jobs:
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Run tests
|
||||
run: './run_tests.sh -toolshed'
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v1
|
||||
id: pip-cache
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-toolshed
|
||||
- name: Run tests
|
||||
run: './run_tests.sh -toolshed'
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Toolshed test results (${{ matrix.python-version }})
|
||||
path: 'galaxy root/run_toolshed_tests.html'
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
name: Unit w/postgres tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
env:
|
||||
GALAXY_TEST_DBURI: 'postgresql://postgres:postgres@localhost:5432/postgres?client_encoding=utf8' # using postgres as the db
|
||||
concurrency:
|
||||
group: py-unit-postgres-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.7']
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:13
|
||||
env:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: postgres
|
||||
ports:
|
||||
- 5432:5432
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-unit-postgres
|
||||
- name: Run migration tests
|
||||
run: ./run_tests.sh -unit test/unit/data/model/migrations/test_migrations.py
|
||||
working-directory: 'galaxy root'
|
||||
@@ -0,0 +1,58 @@
|
||||
name: Unit tests
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'client/**'
|
||||
- 'doc/**'
|
||||
- 'lib/galaxy_test/selenium/**'
|
||||
concurrency:
|
||||
group: py-unit-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.7', '3.10']
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
path: 'galaxy root'
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Get full Python version
|
||||
id: full-python-version
|
||||
shell: bash
|
||||
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")
|
||||
- name: Cache pip dir
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: pip-cache-${{ matrix.python-version }}-${{ hashFiles('galaxy root/requirements.txt') }}
|
||||
- name: Cache galaxy venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: 'galaxy root/.venv'
|
||||
key: gxy-venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('galaxy root/requirements.txt') }}-unit
|
||||
- name: Install ffmpeg
|
||||
run: sudo apt-get update && sudo apt-get -y install ffmpeg
|
||||
- name: Run tests
|
||||
run: ./run_tests.sh --coverage -u
|
||||
working-directory: 'galaxy root'
|
||||
- uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: py-unit
|
||||
working-directory: 'galaxy root'
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: failure()
|
||||
with:
|
||||
name: Unit test results (${{ matrix.python-version }})
|
||||
path: 'galaxy root/run_unit_tests.html'
|
||||
+27
-31
@@ -1,4 +1,5 @@
|
||||
.hg*
|
||||
|
||||
# Downloaded and locally built eggs
|
||||
eggs
|
||||
scripts/scramble/build
|
||||
@@ -21,25 +22,7 @@ lib/galaxy/web/framework/static/scripts
|
||||
lib/galaxy/web/framework/static/style
|
||||
|
||||
# Database stuff
|
||||
database/*.sqlite
|
||||
database/beaker_sessions
|
||||
database/citations
|
||||
database/community_files
|
||||
database/compiled_templates
|
||||
database/dependencies
|
||||
database/files
|
||||
database/job_working_directory
|
||||
database/jobs_directory
|
||||
database/mulled
|
||||
database/object_store_cache
|
||||
database/objects
|
||||
database/openid_consumer_cache
|
||||
database/pbs
|
||||
database/shed_tools
|
||||
database/test_errors
|
||||
database/tmp
|
||||
database/tool_cache
|
||||
database/tool_search_index
|
||||
/database/
|
||||
|
||||
|
||||
# Python bytecode
|
||||
@@ -49,6 +32,10 @@ database/tool_search_index
|
||||
*.lock
|
||||
*.log
|
||||
*.pid
|
||||
celerybeat-schedule
|
||||
|
||||
# Celery state files
|
||||
celerybeat-schedule.*
|
||||
|
||||
# Tool Shed Runtime Files
|
||||
tool_shed_webapp.lock
|
||||
@@ -95,6 +82,7 @@ config/plugins/**/.cache
|
||||
static/welcome.html.*
|
||||
static/welcome.html
|
||||
static/client_build_hash.txt
|
||||
lib/galaxy_test/selenium/jupyter/galaxy_selenium_context.yml
|
||||
|
||||
# Tool data.
|
||||
tool-data/annotation_profiler_options.xml
|
||||
@@ -121,12 +109,13 @@ tool-data/**/*.fa
|
||||
.pytest_cache/
|
||||
assets/
|
||||
test-data-cache
|
||||
run_api_tests.html
|
||||
run_cwl_tests.html
|
||||
run_framework_tests.html
|
||||
run_functional_tests.html
|
||||
run_integration_tests.html
|
||||
run_selenium_tests.html
|
||||
run_toolshed_tests.html
|
||||
run_api_tests.html
|
||||
test/tool_shed/tmp/*
|
||||
.coverage
|
||||
htmlcov
|
||||
@@ -139,7 +128,7 @@ test/unit/**.log
|
||||
.idea
|
||||
.vscode
|
||||
client/**/jsconfig.json
|
||||
|
||||
vetur.config.js
|
||||
|
||||
# Chrom len files
|
||||
*.len
|
||||
@@ -153,18 +142,16 @@ static/plugins
|
||||
static/scripts
|
||||
node_modules
|
||||
bower_components
|
||||
client/galaxy/scripts/libs/*
|
||||
client/galaxy/style/less/*
|
||||
client/src/libs/*
|
||||
# Old galaxy client location
|
||||
client/galaxy
|
||||
|
||||
# Documentation build files.
|
||||
doc/build
|
||||
doc/schema.md
|
||||
doc/source/admin/config_logging_default_yaml.rst
|
||||
doc/source/api/api.rst
|
||||
doc/source/api/ts_api.rst
|
||||
doc/source/dev/schema.md
|
||||
doc/source/dev/schema.rst
|
||||
client/styleguide
|
||||
client/docs/dist
|
||||
|
||||
# webpack stats
|
||||
client/webpack-stats.json
|
||||
@@ -181,7 +168,16 @@ packages/*/*.egg-info
|
||||
*~
|
||||
|
||||
# standalone script + main, or build into dist.
|
||||
config/plugins/visualizations/**/static/dist
|
||||
config/plugins/visualizations/**/static/script.js
|
||||
config/plugins/visualizations/**/static/main.css
|
||||
config/plugins/visualizations/**/static/plugin_build_hash.txt
|
||||
config/plugins/**/static/dist
|
||||
config/plugins/**/static/script.js
|
||||
config/plugins/**/static/main.css
|
||||
config/plugins/**/static/plugin_build_hash.txt
|
||||
config/plugins/**/static/*.map
|
||||
|
||||
# viz-specific build artifacts to ignore (until these are removed from codebase)
|
||||
config/plugins/visualizations/annotate_image/static/jquery.contextMenu.css
|
||||
config/plugins/visualizations/nvd3/nvd3_bar/static/nvd3.js
|
||||
|
||||
# CWL conformance tests
|
||||
lib/galaxy_test/api/cwl/test_cwl_conformance_v1_?.py
|
||||
test/functional/tools/cwl_tools/v1.?/
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
github:
|
||||
prebuilds:
|
||||
# enable for the master/default branch (defaults to true)
|
||||
master: true
|
||||
# enable for all branches in this repo (defaults to false)
|
||||
branches: true
|
||||
# enable for pull requests coming from this repo (defaults to true)
|
||||
pullRequests: true
|
||||
# enable for pull requests coming from forks (defaults to false)
|
||||
pullRequestsFromForks: true
|
||||
# add a "Review in Gitpod" button as a comment to pull requests (defaults to true)
|
||||
addComment: false
|
||||
# add a "Review in Gitpod" button to pull requests (defaults to false)
|
||||
addBadge: false
|
||||
# add a label once the prebuild is ready to pull requests (defaults to false)
|
||||
addLabel: false
|
||||
image: gitpod/workspace-postgres
|
||||
tasks:
|
||||
- init: >
|
||||
cp .vscode/settings_gitpod.json .vscode/settings.json &&
|
||||
cp .vscode/launch_gitpod.json .vscode/launch.json &&
|
||||
pip install psycopg2 &&
|
||||
pip install -r lib/galaxy/dependencies/dev-requirements.txt &&
|
||||
createdb galaxy &&
|
||||
make client
|
||||
- command: cp config/galaxy.yml.sample config/galaxy.yml
|
||||
- command: make client-watch
|
||||
# Ports to expose on workspace startup (optional)
|
||||
ports:
|
||||
- port: 8000
|
||||
vscode:
|
||||
extensions:
|
||||
- ms-python.python
|
||||
- ms-python.vscode-pylance
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
[settings]
|
||||
extend_skip=doc/source/conf.py,lib/galaxy/util/jstree.py
|
||||
force_alphabetical_sort_within_sections=true
|
||||
# Override force_grid_wrap value from profile=black, but black is still happy
|
||||
force_grid_wrap=2
|
||||
# Same line length as for black
|
||||
line_length=120
|
||||
no_lines_before=LOCALFOLDER
|
||||
profile=black
|
||||
reverse_relative=true
|
||||
skip_gitignore=true
|
||||
# Make isort run faster by skipping database
|
||||
skip_glob=database/*
|
||||
src_paths=lib
|
||||
@@ -0,0 +1,194 @@
|
||||
# Stage 1:
|
||||
# - base: ubuntu (default) OR prebuilt image0
|
||||
# - install build tools
|
||||
# - clone playbook
|
||||
# Stage 2: build galaxy client and server in parallel
|
||||
# Stage 2.1:
|
||||
# - run playbook with server build steps only
|
||||
# - remove build artifacts + files not needed in container
|
||||
# Stage 2.2:
|
||||
# - run playbook with client build steps only
|
||||
# - remove build artifacts + files not needed in container
|
||||
# Stage 3:
|
||||
# - create galaxy user + group + directory
|
||||
# - copy galaxy files from stage 2.1 and 2.2
|
||||
# - finalize container (set path, user...)
|
||||
|
||||
# Init ARGs
|
||||
ARG ROOT_DIR=/galaxy
|
||||
ARG SERVER_DIR=$ROOT_DIR/server
|
||||
|
||||
ARG STAGE1_BASE=python:3.7-slim
|
||||
ARG FINAL_STAGE_BASE=$STAGE1_BASE
|
||||
ARG GALAXY_USER=galaxy
|
||||
ARG GALAXY_PLAYBOOK_REPO=https://github.com/galaxyproject/galaxy-docker-k8s
|
||||
ARG GALAXY_PLAYBOOK_BRANCH=v2.0.0
|
||||
|
||||
ARG GIT_COMMIT=unspecified
|
||||
ARG BUILD_DATE=unspecified
|
||||
ARG IMAGE_TAG=unspecified
|
||||
|
||||
#======================================================
|
||||
# Stage 1 - Setup common requirements for build
|
||||
#======================================================
|
||||
FROM $STAGE1_BASE AS stage1
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG SERVER_DIR
|
||||
ARG GALAXY_PLAYBOOK_REPO
|
||||
ARG GALAXY_PLAYBOOK_BRANCH
|
||||
|
||||
# Init Env
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
ENV LANG=en_US.UTF-8
|
||||
|
||||
# Install build dependencies + ansible
|
||||
RUN set -xe; \
|
||||
echo "Acquire::http {No-Cache=True;};" > /etc/apt/apt.conf.d/no-cache \
|
||||
&& apt-get -qq update && apt-get install -y --no-install-recommends \
|
||||
locales locales-all \
|
||||
git \
|
||||
make \
|
||||
libc-dev \
|
||||
bzip2 \
|
||||
gcc \
|
||||
&& pip install --no-cache virtualenv 'ansible<2.10' \
|
||||
&& apt-get autoremove -y && apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/*
|
||||
|
||||
# Remove context from previous build; copy current context; run playbook
|
||||
WORKDIR /tmp/ansible
|
||||
RUN rm -rf *
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
RUN git clone --depth 1 --branch $GALAXY_PLAYBOOK_BRANCH $GALAXY_PLAYBOOK_REPO galaxy-docker
|
||||
WORKDIR /tmp/ansible/galaxy-docker
|
||||
RUN ansible-galaxy install -r requirements.yml -p roles --force-with-deps
|
||||
|
||||
# Add Galaxy source code
|
||||
COPY . $SERVER_DIR/
|
||||
|
||||
#======================================================
|
||||
# Stage 2.1 - Build galaxy server
|
||||
#======================================================
|
||||
FROM stage1 AS server_build
|
||||
ARG SERVER_DIR
|
||||
|
||||
RUN ansible-playbook -i localhost, playbook.yml -v -e galaxy_build_client=False -e galaxy_virtualenv_command=virtualenv
|
||||
|
||||
RUN cat /galaxy/server/lib/galaxy/dependencies/conditional-requirements.txt | grep psycopg2-binary | xargs /galaxy/server/.venv/bin/pip install
|
||||
|
||||
# Remove build artifacts + files not needed in container
|
||||
WORKDIR $SERVER_DIR
|
||||
# Save commit hash of HEAD before zapping git folder
|
||||
RUN git rev-parse HEAD > GITREVISION
|
||||
RUN rm -rf \
|
||||
.ci \
|
||||
.git \
|
||||
.venv/include/node \
|
||||
.venv/src/node* \
|
||||
doc \
|
||||
test \
|
||||
test-data
|
||||
# Clean up *all* node_modules, including plugins. Everything is already built+staged.
|
||||
RUN find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
|
||||
|
||||
#======================================================
|
||||
# Stage 2.2 - Build galaxy client
|
||||
#======================================================
|
||||
FROM stage1 AS client_build
|
||||
ARG SERVER_DIR
|
||||
|
||||
RUN ansible-playbook -i localhost, playbook.yml -v --tags "galaxy_build_client" -e galaxy_virtualenv_command=virtualenv
|
||||
|
||||
WORKDIR $SERVER_DIR
|
||||
RUN rm -rf \
|
||||
.ci \
|
||||
.git \
|
||||
.venv/include/node \
|
||||
.venv/src/node* \
|
||||
doc \
|
||||
test \
|
||||
test-data
|
||||
# Clean up *all* node_modules, including plugins. Everything is already built+staged.
|
||||
RUN find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
|
||||
|
||||
#======================================================
|
||||
# Stage 3 - Build final image based on previous stages
|
||||
#======================================================
|
||||
FROM $FINAL_STAGE_BASE
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG ROOT_DIR
|
||||
ARG SERVER_DIR
|
||||
ARG GALAXY_USER
|
||||
|
||||
ARG GIT_COMMIT
|
||||
ARG BUILD_DATE
|
||||
ARG IMAGE_TAG
|
||||
|
||||
LABEL org.opencontainers.image.title="Galaxy Minimal Image" \
|
||||
org.opencontainers.image.description="A size optimized image for Galaxy targeting k8s and ci applications" \
|
||||
org.opencontainers.image.authors="galaxyproject.org" \
|
||||
org.opencontainers.image.vendor="Galaxy Project" \
|
||||
org.opencontainers.image.documentation="https://github.com/galaxyproject/galaxy-docker-k8s" \
|
||||
org.opencontainers.image.licenses="MIT" \
|
||||
org.opencontainers.image.version="$IMAGE_TAG" \
|
||||
org.opencontainers.image.url="https://github.com/galaxyproject/galaxy-docker-k8s" \
|
||||
org.opencontainers.image.source="https://github.com/galaxyproject/galaxy.git" \
|
||||
org.opencontainers.image.revision=$GIT_COMMIT \
|
||||
org.opencontainers.image.created=$BUILD_DATE
|
||||
|
||||
# Init Env
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
ENV LANG=en_US.UTF-8
|
||||
|
||||
# Install procps (contains kill, ps etc.), less, curl, vim-tiny and nano-tiny
|
||||
# for convenience and debugging purposes. Nano and vim commands are aliased
|
||||
# to their tiny variants using the debian alternatives system.
|
||||
# Bzip2 and virtualenv are installed for backwards compatibility with older
|
||||
# versions of this image which was based on Ubuntu and contained these
|
||||
# utilities.
|
||||
RUN set -xe; \
|
||||
echo "Acquire::http {No-Cache=True;};" > /etc/apt/apt.conf.d/no-cache \
|
||||
&& apt-get -qq update && apt-get install -y --no-install-recommends \
|
||||
locales \
|
||||
vim-tiny \
|
||||
nano-tiny \
|
||||
curl \
|
||||
procps \
|
||||
less \
|
||||
bzip2 \
|
||||
tini \
|
||||
&& update-alternatives --install /usr/bin/nano nano /bin/nano-tiny 0 \
|
||||
&& update-alternatives --install /usr/bin/vim vim /usr/bin/vim.tiny 0 \
|
||||
&& echo "set nocompatible\nset backspace=indent,eol,start" >> /usr/share/vim/vimrc.tiny \
|
||||
&& echo "$LANG UTF-8" > /etc/locale.gen \
|
||||
&& locale-gen $LANG && update-locale LANG=$LANG \
|
||||
&& apt-get autoremove -y && apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/*
|
||||
|
||||
# Create Galaxy user, group, directory; chown
|
||||
RUN set -xe; \
|
||||
adduser --system --group $GALAXY_USER \
|
||||
&& mkdir -p $SERVER_DIR \
|
||||
&& chown $GALAXY_USER:$GALAXY_USER $ROOT_DIR -R
|
||||
|
||||
WORKDIR $ROOT_DIR
|
||||
# Copy galaxy files to final image
|
||||
# The chown value MUST be hardcoded (see https://github.com/moby/moby/issues/35018)
|
||||
COPY --chown=$GALAXY_USER:$GALAXY_USER --from=server_build $ROOT_DIR .
|
||||
COPY --chown=$GALAXY_USER:$GALAXY_USER --from=client_build $SERVER_DIR/static ./server/static
|
||||
|
||||
WORKDIR $SERVER_DIR
|
||||
|
||||
# The data in version.json will be displayed in Galaxy's /api/version endpoint
|
||||
RUN printf "{\n \"git_commit\": \"$(cat GITREVISION)\",\n \"build_date\": \"$BUILD_DATE\",\n \"image_tag\": \"$IMAGE_TAG\"\n}\n" > version.json
|
||||
|
||||
EXPOSE 8080
|
||||
USER $GALAXY_USER
|
||||
|
||||
ENV PATH="$SERVER_DIR/.venv/bin:${PATH}"
|
||||
ENV GALAXY_CONFIG_CONDA_AUTO_INIT=False
|
||||
|
||||
ENTRYPOINT ["tini", "--"]
|
||||
|
||||
# [optional] to run:
|
||||
CMD galaxy
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
GALAXY_TEST_TOOL_CONF="lib/galaxy/config/sample/tool_conf.xml.sample,test/functional/tools/samples_tool_conf.xml"
|
||||
Vendored
+46
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "GalaxyFastAPI uvicorn",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"module": "uvicorn",
|
||||
"args": ["--app-dir", "lib", "--factory", "galaxy.webapps.galaxy.fast_factory:factory"],
|
||||
"env": {
|
||||
"GALAXY_CONFIG_FILE": "${workspaceFolder}/config/galaxy.yml",
|
||||
"GALAXY_CONDA_AUTO_INIT": "false",
|
||||
"GALAXY_CONFIG_TOOL_CONFIG_FILE": "lib/galaxy/config/sample/tool_conf.xml.sample,test/functional/tools/samples_tool_conf.xml",
|
||||
"GALAXY_CONFIG_DATABASE_CONNECTION": "postgresql://localhost/galaxy"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Tool test framework",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/.venv/bin/pytest",
|
||||
"args": [
|
||||
"test/functional/test_toolbox_pytest.py",
|
||||
"-m",
|
||||
"tool",
|
||||
"-k",
|
||||
"job_properties_test_2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"name": "debug selected jest unit test",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/client/node_modules/jest/bin/jest",
|
||||
"args": [
|
||||
"--runInBand",
|
||||
"--config",
|
||||
"${workspaceFolder}/client/tests/jest/jest.config.js",
|
||||
"${file}"
|
||||
],
|
||||
"cwd": "${workspaceFolder}/client",
|
||||
"console": "integratedTerminal",
|
||||
"disableOptimisticBPs": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"python.testing.pytestArgs": [
|
||||
"--doctest-modules",
|
||||
"lib/galaxy_test/api/",
|
||||
"lib/galaxy/datatypes",
|
||||
"test/unit",
|
||||
"test/integration",
|
||||
"lib/galaxy_test/selenium/"
|
||||
],
|
||||
"python.testing.pytestEnabled": true,
|
||||
"python.envFile": "${workspaceFolder}/.vscode/.test.env"
|
||||
}
|
||||
|
||||
+25
-6
@@ -1,5 +1,16 @@
|
||||
Galaxy Project Code of Conduct
|
||||
==============================
|
||||
# Galaxy Project Code of Conduct
|
||||
|
||||
## Note: Change is Coming
|
||||
|
||||
Since 2015 the Galaxy Project Code of Conduct has resided here, and updates to it have been coordinated by the Committers Group for this repo.
|
||||
|
||||
This code of conduct has served us reasonably well over the years, but it is time for a refresh. Since 2015 the world has become much more aware of the need for codes of conduct, and best practices for creating and enforcing them have moved forward significantly.
|
||||
|
||||
**As a result it is past time to update both our code of conduct and our process for maintaining it.** The Galaxy Outreach and Training [Working Group](https://galaxyproject.org/community/wg/) is currently working on a first draft of a new code and new processes. The final code and processes we adopt will be [implemented](https://galaxyproject.org/community/coc/) only after it has been discussed, revised, and approved by the community.
|
||||
|
||||
Until that happens this will remain the Galaxy Project Code of Conduct.
|
||||
|
||||
# Code of Conduct
|
||||
|
||||
This code of conduct outlines our expectations for participants within the
|
||||
Galaxy community, as well as steps to reporting unacceptable behavior. We are
|
||||
@@ -71,10 +82,18 @@ participants with disabilities.
|
||||
### Reporting Issues
|
||||
|
||||
If you experience or witness unacceptable behavior, or have any other concerns,
|
||||
please report it by contacting Dave Clements (clementsgalaxy@gmail.com). To
|
||||
report an issue involving Dave Clements please email James Taylor
|
||||
(james@taylorlab.org). All reports will be handled with discretion. In your
|
||||
report please include:
|
||||
please report it to any combination of the following people that makes you feel
|
||||
the most comfortable:
|
||||
|
||||
- Dave Clements (clementsgalaxy@gmail.com). Dave is the Galaxy Project community
|
||||
outreach manager and has experience handling Code of Conduct related issues.
|
||||
- Dr. Mike Schatz (mschatz@cs.jhu.edu). Mike is Dave Clements' direct manager
|
||||
and issues related to Dave in some way should be reported to Mike.
|
||||
- Helena Rasche (helena.rasche@gmail.com). Helena is a well-known, trusted
|
||||
community member, is LGBT+, and has completely separate funding and
|
||||
institutional affiliation from Dave and Mike.
|
||||
|
||||
All reports will be handled with discretion. In your report please include:
|
||||
|
||||
- Your contact information.
|
||||
|
||||
|
||||
+28
-10
@@ -41,7 +41,10 @@ Git](https://swcarpentry.github.io/git-novice/) tutorial is a good place to
|
||||
start. More learning resources are listed at
|
||||
https://help.github.com/en/github/getting-started-with-github/git-and-github-learning-resources
|
||||
|
||||
1. Make sure you have a free [GitHub](https://github.com/) account.
|
||||
1. Make sure you have a free [GitHub](https://github.com/) account. To increase
|
||||
the security of your account, we strongly recommend that you configure
|
||||
[two-factor authentication](https://docs.github.com/en/github/authenticating-to-github/securing-your-account-with-two-factor-authentication-2fa).
|
||||
Additionally, you may want to [sign your commits](https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification).
|
||||
|
||||
2. Fork the [galaxy repository](https://github.com/galaxyproject/galaxy) on
|
||||
GitHub to make your changes. To keep your copy up to date with respect to
|
||||
@@ -88,10 +91,23 @@ https://help.github.com/en/github/getting-started-with-github/git-and-github-lea
|
||||
Developers reviewing your pull request will be happy to help you add or run
|
||||
the relevant tests as part of the pull request review process.
|
||||
|
||||
6. Commit and push your changes to your
|
||||
6. Write a useful and properly formatted commit message.
|
||||
Follow [these guidelines and template](https://git-scm.com/book/en/v2/Distributed-Git-Contributing-to-a-Project#_commit_guidelines),
|
||||
in particular start your message with a short imperative sentence on a single
|
||||
line, possibly followed by a blank line and a more detailed explanation.
|
||||
|
||||
In the detailed explanation it's good to include relevant external references
|
||||
(e.g. GitHub issue fixed) using full URLs, and errors or tracebacks the
|
||||
commit is supposed to fix.
|
||||
You can use the Markdown syntax for lists and code highlighting, wrapping the
|
||||
explanation text at 72 characters when possible.
|
||||
|
||||
Example of a good commit message: https://github.com/galaxyproject/galaxy/commit/0429c4d515536f9cca6b70b2abeb019de807c955
|
||||
|
||||
7. Commit and push your changes to your
|
||||
[fork](https://help.github.com/en/github/using-git/pushing-commits-to-a-remote-repository).
|
||||
|
||||
7. Open a [pull
|
||||
8. Open a [pull
|
||||
request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request)
|
||||
with these changes. Your pull request message ideally should include:
|
||||
|
||||
@@ -101,10 +117,10 @@ https://help.github.com/en/github/getting-started-with-github/git-and-github-lea
|
||||
|
||||
* How to test the changes, if you haven't included specific tests already.
|
||||
|
||||
8. The pull request should pass all the continuous integration tests which are
|
||||
9. The pull request should pass all the continuous integration tests which are
|
||||
automatically started by GitHub using e.g. Travis CI.
|
||||
|
||||
9. Your pull request will be handled according to [some
|
||||
10. Your pull request will be handled according to [some
|
||||
rules](doc/source/project/organization.rst#handling-pull-requests).
|
||||
|
||||
## Style guidelines
|
||||
@@ -114,11 +130,13 @@ https://help.github.com/en/github/getting-started-with-github/git-and-github-lea
|
||||
- Galaxy follows [PEP-8](https://www.python.org/dev/peps/pep-0008/), with
|
||||
particular emphasis on readability being the ultimate goal:
|
||||
- 4 spaces (not tabs!) per indentation level
|
||||
- divergences from PEP-8 are listed in the `[flake8]` section of the `setup.cfg`
|
||||
file.
|
||||
- Python imports should be ordered following the
|
||||
[smarkets](https://github.com/PyCQA/flake8-import-order/blob/master/tests/test_cases/complete_smarkets.py)
|
||||
style.
|
||||
- divergences from PEP-8 are listed in the `[flake8]` section of the
|
||||
`setup.cfg` file
|
||||
- The Python code base is automatically formatted using
|
||||
[isort](https://pycqa.github.io/isort/) (for imports) and
|
||||
[black](https://black.readthedocs.io). To easily format your Python code
|
||||
before submitting your contribution, please either use `make diff-format`
|
||||
or run `isort FILE; black FILE` for each FILE you modify.
|
||||
- Python [docstrings](http://www.python.org/dev/peps/pep-0257/) need to be in
|
||||
[reStructured Text (RST)](https://docutils.sourceforge.io/rst.html) format and
|
||||
compatible with [Sphinx](https://www.sphinx-doc.org).
|
||||
|
||||
@@ -132,6 +132,7 @@ The following individuals have contributed code to Galaxy:
|
||||
* Michael Sauria <crockopotamus@gmail.com>
|
||||
* Andrea Sbardellati <andrea.sbardellati@crs4.it>
|
||||
* Ian Schenck <ian@bx.psu.edu>
|
||||
* Jelle Scholtalbers <j.scholtalbers@gmail.com>
|
||||
* Nick Semenkovich <semenko@alum.mit.edu>
|
||||
* Varun Shankar <varunshankar55@gmail.com>
|
||||
* Matthew Shirley <mdshw5@gmail.com>
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
# Location of virtualenv used for development.
|
||||
VENV?=.venv
|
||||
# Source virtualenv to execute command (flake8, sphinx, twine, etc...)
|
||||
IN_VENV=if [ -f $(VENV)/bin/activate ]; then . $(VENV)/bin/activate; fi;
|
||||
RELEASE_CURR:=16.01
|
||||
RELEASE_CURR_MINOR_NEXT:=$(shell $(IN_VENV) python scripts/bootstrap_history.py --print-next-minor-version)
|
||||
RELEASE_NEXT:=16.04
|
||||
# TODO: This needs to be updated with create_release_rc
|
||||
#RELEASE_NEXT_BRANCH:=release_$(RELEASE_NEXT)
|
||||
RELEASE_NEXT_BRANCH:=dev
|
||||
IN_VENV=if [ -f "$(VENV)/bin/activate" ]; then . "$(VENV)/bin/activate"; fi;
|
||||
RELEASE_CURR:=22.05
|
||||
RELEASE_UPSTREAM:=upstream
|
||||
MY_UPSTREAM:=origin
|
||||
TARGET_BRANCH=$(RELEASE_UPSTREAM)/dev
|
||||
CONFIG_MANAGE=$(IN_VENV) python lib/galaxy/config/config_manage.py
|
||||
PROJECT_URL?=https://github.com/galaxyproject/galaxy
|
||||
DOCS_DIR=doc
|
||||
@@ -18,6 +13,13 @@ SLIDESHOW_DIR=$(DOC_SOURCE_DIR)/slideshow
|
||||
OPEN_RESOURCE=bash -c 'open $$0 || xdg-open $$0'
|
||||
SLIDESHOW_TO_PDF?=bash -c 'docker run --rm -v `pwd`:/cwd astefanutti/decktape /cwd/$$0 /cwd/`dirname $$0`/`basename -s .html $$0`.pdf'
|
||||
YARN := $(shell command -v yarn 2> /dev/null)
|
||||
YARN_INSTALL_OPTS=--network-timeout 300000 --check-files
|
||||
CWL_TARGETS := test/functional/tools/cwl_tools/v1.0/conformance_tests.yaml \
|
||||
test/functional/tools/cwl_tools/v1.1/conformance_tests.yaml \
|
||||
test/functional/tools/cwl_tools/v1.2/conformance_tests.yaml \
|
||||
lib/galaxy_test/api/cwl/test_cwl_conformance_v1_0.py \
|
||||
lib/galaxy_test/api/cwl/test_cwl_conformance_v1_1.py \
|
||||
lib/galaxy_test/api/cwl/test_cwl_conformance_v1_2.py
|
||||
|
||||
all: help
|
||||
@echo "This makefile is used for building Galaxy's JS client, documentation, and drive the release process. A sensible all target is not implemented."
|
||||
@@ -30,9 +32,19 @@ docs: ## Generate HTML documentation.
|
||||
$(IN_VENV) $(MAKE) -C doc clean
|
||||
$(IN_VENV) $(MAKE) -C doc html
|
||||
|
||||
docs-develop: ## Fast doc generation and more warnings (for development)
|
||||
$(IN_VENV) GALAXY_DOCS_SKIP_VIEW_CODE=1 SPHINXOPTS='-j 4' $(MAKE) -C doc html
|
||||
|
||||
setup-venv:
|
||||
if [ ! -f $(VENV)/bin/activate ]; then bash scripts/common_startup.sh --dev-wheels; fi
|
||||
|
||||
diff-format: ## Format Python code changes since last commit
|
||||
$(IN_VENV) darker .
|
||||
|
||||
format: ## Format Python code base
|
||||
$(IN_VENV) isort .
|
||||
$(IN_VENV) black .
|
||||
|
||||
list-dependency-updates: setup-venv
|
||||
$(IN_VENV) pip list --outdated --format=columns
|
||||
|
||||
@@ -52,12 +64,6 @@ open-docs: docs _open-docs ## generate Sphinx HTML documentation and open in bro
|
||||
open-project: ## open project on github
|
||||
$(OPEN_RESOURCE) $(PROJECT_URL)
|
||||
|
||||
lint: ## check style using tox and flake8 for Python 2 and Python 3
|
||||
$(IN_VENV) tox -e py27-lint && tox -e py34-lint
|
||||
|
||||
uwsgi-rebuild-validation: ## rebuild uwsgi_config.yml kwalify schema against latest uwsgi master.
|
||||
$(CONFIG_MANAGE) build_uwsgi_yaml
|
||||
|
||||
tool-shed-config-validate: ## validate tool shed YAML configuration file
|
||||
$(CONFIG_MANAGE) validate tool_shed
|
||||
|
||||
@@ -129,21 +135,36 @@ release-check-blocking-prs: ## Check github for release blocking PRs
|
||||
release-bootstrap-history: ## bootstrap history for a new release
|
||||
$(IN_VENV) python scripts/bootstrap_history.py --release $(RELEASE_CURR)
|
||||
|
||||
build-dependencies-docker: ## Builds the docker container used for dependency updates
|
||||
$(MAKE) -C lib/galaxy/dependencies/pipfiles/docker
|
||||
update-lint-requirements:
|
||||
./lib/galaxy/dependencies/update_lint_requirements.sh
|
||||
|
||||
update-dependencies: build-dependencies-docker ## update linting + dev dependencies
|
||||
sh lib/galaxy/dependencies/pipfiles/update.sh -d
|
||||
update-dependencies: update-lint-requirements ## update pinned and dev dependencies
|
||||
$(IN_VENV) ./lib/galaxy/dependencies/update.sh
|
||||
|
||||
update-and-commit-dependencies: build-dependencies-docker ## update and commit linting + dev dependencies
|
||||
sh lib/galaxy/dependencies/pipfiles/update.sh -d -c
|
||||
$(CWL_TARGETS):
|
||||
./scripts/update_cwl_conformance_tests.sh
|
||||
|
||||
generate-cwl-conformance-tests: $(CWL_TARGETS) ## Initialise CWL conformance tests
|
||||
|
||||
clean-cwl-conformance-tests: ## Clean CWL conformance tests
|
||||
for f in $(CWL_TARGETS); do \
|
||||
if [ $$(basename "$$f") = conformance_tests.yaml ]; then \
|
||||
rm -rf $$(dirname "$$f"); \
|
||||
else \
|
||||
rm -f "$$f"; \
|
||||
fi \
|
||||
done
|
||||
|
||||
update-cwl-conformance-tests: ## update CWL conformance tests
|
||||
$(MAKE) clean-cwl-conformance-tests
|
||||
$(MAKE) generate-cwl-conformance-tests
|
||||
|
||||
node-deps: ## Install NodeJS dependencies.
|
||||
ifndef YARN
|
||||
@echo "Could not find yarn, which is required to build the Galaxy client.\nTo install yarn, please visit \033[0;34mhttps://yarnpkg.com/en/docs/install\033[0m for instructions, and package information for all platforms.\n"
|
||||
false;
|
||||
else
|
||||
cd client && yarn install --network-timeout 300000 --check-files
|
||||
cd client && yarn install $(YARN_INSTALL_OPTS)
|
||||
endif
|
||||
|
||||
|
||||
@@ -163,9 +184,9 @@ client-watch: node-deps ## A useful target for parallel development building. S
|
||||
cd client && yarn run watch
|
||||
|
||||
client-dev-server: node-deps ## Starts a webpack dev server for client development (HMR enabled)
|
||||
cd client && yarn run webpack-dev-server
|
||||
cd client && yarn run serve
|
||||
|
||||
client-test: node-deps ## Run JS unit tests via Karma
|
||||
client-test: node-deps ## Run JS unit tests
|
||||
cd client && yarn run test
|
||||
|
||||
client-eslint: node-deps # Run client linting
|
||||
@@ -176,101 +197,20 @@ client-format-check: node-deps # Run client formatting check
|
||||
|
||||
client-lint: client-eslint client-format-check ## ES lint and check format of client
|
||||
|
||||
client-test-watch: client ## Watch and run qunit tests on changes via Karma
|
||||
cd client && yarn run test-watch
|
||||
client-test-watch: client ## Watch and run all client unit tests on changes
|
||||
cd client && yarn run jest-watch
|
||||
|
||||
serve-selenium-notebooks: ## Serve testing notebooks for Jupyter
|
||||
cd lib && export PYTHONPATH=`pwd`; jupyter notebook --notebook-dir=galaxy_test/selenium/jupyter
|
||||
|
||||
# Release Targets
|
||||
release-create-rc: release-ensure-upstream ## Create a release-candidate branch
|
||||
git checkout dev
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) dev
|
||||
git push $(MY_UPSTREAM) dev
|
||||
git checkout -b release_$(RELEASE_CURR)
|
||||
git push $(MY_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git push $(RELEASE_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git checkout -b version-$(RELEASE_CURR)
|
||||
sed -i.bak -e "s/^VERSION_MAJOR = .*/VERSION_MAJOR = \"$(RELEASE_CURR)\"/" lib/galaxy/version.py
|
||||
sed -i.bak -e "s/^VERSION_MINOR = .*/VERSION_MINOR = \"rc1\"/" lib/galaxy/version.py
|
||||
rm -f lib/galaxy/version.py.bak
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Update version to $(RELEASE_CURR).rc1"
|
||||
git checkout dev
|
||||
release-create-rc: ## Create a release-candidate branch or new release-candidate version
|
||||
$(IN_VENV) ./scripts/release.sh -c
|
||||
|
||||
git checkout -b version-$(RELEASE_NEXT).dev
|
||||
sed -i.bak -e "s/^VERSION_MAJOR = .*/VERSION_MAJOR = \"$(RELEASE_NEXT)\"/" lib/galaxy/version.py
|
||||
rm -f lib/galaxy/version.py.bak
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Update version to $(RELEASE_NEXT).dev"
|
||||
release-create: ## Create a release branch
|
||||
$(IN_VENV) ./scripts/release.sh
|
||||
|
||||
-git merge version-$(RELEASE_CURR)
|
||||
git checkout --ours lib/galaxy/version.py
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Merge branch 'version-$(RELEASE_CURR)' into version-$(RELEASE_NEXT).dev"
|
||||
git push $(MY_UPSTREAM) version-$(RELEASE_CURR):version-$(RELEASE_CURR)
|
||||
git push $(MY_UPSTREAM) version-$(RELEASE_NEXT).dev:version-$(RELEASE_NEXT).dev
|
||||
git checkout dev
|
||||
# TODO: Use hub to automate these PR creations or push directly.
|
||||
@echo "Open a PR from version-$(RELEASE_CURR) of your fork to release_$(RELEASE_CURR)"
|
||||
@echo "Open a PR from version-$(RELEASE_NEXT).dev of your fork to dev"
|
||||
|
||||
release-create: release-ensure-upstream ## Create a release branch
|
||||
git checkout master
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) master
|
||||
git push $(MY_UPSTREAM) master
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) release_$(RELEASE_CURR)
|
||||
#git push $(MY_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git checkout dev
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) dev
|
||||
#git push $(MY_UPSTREAM) dev
|
||||
# Test run of merging. If there are conflicts, it will fail here.
|
||||
git merge release_$(RELEASE_CURR)
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
sed -i.bak -e "s/^VERSION_MINOR = .*/VERSION_MINOR = None/" lib/galaxy/version.py
|
||||
rm -f lib/galaxy/version.py.bak
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Update version to $(RELEASE_CURR)"
|
||||
git tag -m "Tag version $(RELEASE_CURR)" v$(RELEASE_CURR)
|
||||
|
||||
git checkout dev
|
||||
-git merge release_$(RELEASE_CURR)
|
||||
git checkout --ours lib/galaxy/version.py
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Merge branch 'release_$(RELEASE_CURR)' into dev"
|
||||
git checkout master
|
||||
git merge release_$(RELEASE_CURR)
|
||||
git push $(RELEASE_UPSTREAM) release_$(RELEASE_CURR):release_$(RELEASE_CURR)
|
||||
git push $(RELEASE_UPSTREAM) dev:dev
|
||||
git push $(RELEASE_UPSTREAM) master:master
|
||||
git push $(RELEASE_UPSTREAM) --tags
|
||||
|
||||
release-create-point: ## Create a point release
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) master
|
||||
git push $(MY_UPSTREAM) master
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) release_$(RELEASE_CURR)
|
||||
#git push $(MY_UPSTREAM) release_$(RELEASE_CURR)
|
||||
git checkout $(RELEASE_NEXT_BRANCH)
|
||||
git pull --ff-only $(RELEASE_UPSTREAM) $(RELEASE_NEXT_BRANCH)
|
||||
#git push $(MY_UPSTREAM) $(RELEASE_NEXT_BRANCH)
|
||||
git merge release_$(RELEASE_CURR)
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
sed -i.bak -e "s/^VERSION_MINOR = .*/VERSION_MINOR = \"$(RELEASE_CURR_MINOR_NEXT)\"/" lib/galaxy/version.py
|
||||
rm -f lib/galaxy/version.py.bak
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Update version to $(RELEASE_CURR).$(RELEASE_CURR_MINOR_NEXT)"
|
||||
git tag -m "Tag version $(RELEASE_CURR).$(RELEASE_CURR_MINOR_NEXT)" v$(RELEASE_CURR).$(RELEASE_CURR_MINOR_NEXT)
|
||||
git checkout $(RELEASE_NEXT_BRANCH)
|
||||
-git merge release_$(RELEASE_CURR)
|
||||
git checkout --ours lib/galaxy/version.py
|
||||
git add lib/galaxy/version.py
|
||||
git commit -m "Merge branch 'release_$(RELEASE_CURR)' into $(RELEASE_NEXT_BRANCH)"
|
||||
git checkout master
|
||||
git merge release_$(RELEASE_CURR)
|
||||
#git push origin release_$(RELEASE_CURR):release_$(RELEASE_CURR)
|
||||
#git push origin $(RELEASE_NEXT_BRANCH):release_$(RELEASE_NEXT_BRANCH)
|
||||
#git push origin master:master
|
||||
#git push origin --tags
|
||||
git checkout release_$(RELEASE_CURR)
|
||||
release-create-point: release-create ## Create a point release
|
||||
|
||||
.PHONY: help
|
||||
|
||||
|
||||
+2
-2
@@ -24,12 +24,12 @@ Community support is available at `Galaxy Help <https://help.galaxyproject.org/>
|
||||
Galaxy Quickstart
|
||||
=================
|
||||
|
||||
Galaxy requires Python 3.5 or 3.6 . To check your Python version, run:
|
||||
Galaxy requires Python 3.7 . To check your Python version, run:
|
||||
|
||||
.. code:: console
|
||||
|
||||
$ python -V
|
||||
Python 3.6.10
|
||||
Python 3.7.6
|
||||
|
||||
Start Galaxy:
|
||||
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
. ./scripts/common_startup_functions.sh
|
||||
|
||||
setup_python
|
||||
|
||||
python ./scripts/check_model.py "$@"
|
||||
|
||||
[ $? -ne 0 ] && exit 1;
|
||||
exit 0;
|
||||
@@ -1,6 +0,0 @@
|
||||
*.test.js
|
||||
galaxy/scripts/qunit
|
||||
galaxy/scripts/mocha
|
||||
galaxy/scripts/libs
|
||||
galaxy/scripts/nls
|
||||
galaxy/scripts/legacy
|
||||
@@ -1,47 +0,0 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/strongly-recommended"
|
||||
//"airbnb-base", eventually
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
commonjs: true,
|
||||
es6: true,
|
||||
node: true,
|
||||
mocha: true
|
||||
},
|
||||
parserOptions: {
|
||||
parser: "babel-eslint",
|
||||
sourceType: "module"
|
||||
},
|
||||
rules: {
|
||||
// Standard rules
|
||||
"no-console": "off",
|
||||
"no-unused-vars": ["error", { args: "none" }],
|
||||
"prefer-const": "error",
|
||||
"one-var": ["error", "never"],
|
||||
|
||||
"vue/valid-v-slot": "error",
|
||||
"vue/v-slot-style": ["error", { atComponent: "v-slot", default: "v-slot", named: "longform" }],
|
||||
|
||||
// Vue TODO (enable these)
|
||||
"vue/require-default-prop": "warn",
|
||||
"vue/require-prop-types": "warn",
|
||||
"vue/prop-name-casing": "warn",
|
||||
|
||||
// Prettier compromises/workarounds -- mostly #wontfix?
|
||||
"vue/html-indent": "off",
|
||||
"vue/max-attributes-per-line": "off",
|
||||
"vue/html-self-closing": "off",
|
||||
"vue/singleline-html-element-content-newline": "off",
|
||||
"vue/multiline-html-element-content-newline": "off",
|
||||
"vue/html-closing-bracket-newline": "off",
|
||||
"vue/html-closing-bracket-spacing": "off"
|
||||
},
|
||||
globals: {
|
||||
// chai tests
|
||||
assert: true,
|
||||
expect: true
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/strongly-recommended"
|
||||
//"airbnb-base", eventually
|
||||
],
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"jest": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"parser": "@babel/eslint-parser",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
// Standard rules
|
||||
"no-console": "off",
|
||||
"no-unused-vars": ["error", { "args": "none" }],
|
||||
"prefer-const": "error",
|
||||
"one-var": ["error", "never"],
|
||||
"curly": "error",
|
||||
|
||||
"vue/valid-v-slot": "error",
|
||||
"vue/v-slot-style": ["error", { "atComponent": "v-slot", "default": "v-slot", "named": "longform" }],
|
||||
|
||||
// Vue TODO (enable these)
|
||||
"vue/require-default-prop": "warn",
|
||||
"vue/require-prop-types": "warn",
|
||||
"vue/prop-name-casing": "warn",
|
||||
"vue/multi-word-component-names": "warn",
|
||||
|
||||
// Prettier compromises/workarounds -- mostly #wontfix?
|
||||
"vue/html-indent": "off",
|
||||
"vue/max-attributes-per-line": "off",
|
||||
"vue/html-self-closing": "off",
|
||||
"vue/singleline-html-element-content-newline": "off",
|
||||
"vue/multiline-html-element-content-newline": "off",
|
||||
"vue/html-closing-bracket-newline": "off",
|
||||
"vue/html-closing-bracket-spacing": "off"
|
||||
},
|
||||
"ignorePatterns": ["src/qunit", "src/mocha", "src/libs", "src/nls", "src/legacy"]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
12.16.3
|
||||
16.13.2
|
||||
|
||||
+74
-231
@@ -1,36 +1,35 @@
|
||||
Client Build System
|
||||
===================
|
||||
# Client Build System
|
||||
|
||||
Installs, stages, and builds the client-side scripts necessary for running the
|
||||
Galaxy webapp. When started through `run.sh` or any other method that utilizes
|
||||
`scripts/common_startup.sh`, Galaxy will (since 18.09) *automatically* build
|
||||
`scripts/common_startup.sh`, Galaxy will (since 18.09) _automatically_ build
|
||||
the client as a part of server startup, when it detects changes, unless that
|
||||
functionality is explicitly disabled.
|
||||
|
||||
The base dependencies used are Node.js and Yarn. Galaxy now includes these in
|
||||
The base dependencies used are Node.js and Yarn. Galaxy now includes these in
|
||||
the virtual environment, and they can be accessed by activating that with `.
|
||||
.venv/bin/activate` from the Galaxy root directory.
|
||||
|
||||
If you'd like to install your own dependencies, on OSX the easiest way to get
|
||||
set up is using `homebrew` and the command `brew install nodejs yarn`. More
|
||||
set up is using `homebrew` and the command `brew install nodejs yarn`. More
|
||||
information, including instructions for other platforms, is available at
|
||||
https://nodejs.org/ and https://yarnpkg.com/ .
|
||||
[https://nodejs.org](https://nodejs.org) and
|
||||
[https://yarnpkg.com/](https://yarnpkg.com).
|
||||
|
||||
The Galaxy client build has necessarily grown more complex in the past several
|
||||
years, but we are still trying to keep things as simple as possible for
|
||||
everyone. If you're having any trouble with building the client after
|
||||
following the instructions below, please create an issue on GitHub or reach out
|
||||
for help directly on Gitter at https://gitter.im/galaxyproject/Lobby .
|
||||
everyone. If you're having any trouble with building the client after following
|
||||
the instructions below, please create an issue on GitHub or reach out for help
|
||||
directly on Gitter at
|
||||
[https://gitter.im/galaxyproject/Lobby](https://gitter.im/galaxyproject/Lobby).
|
||||
|
||||
|
||||
Complete Client Build
|
||||
=====================
|
||||
## Complete Client Build
|
||||
|
||||
There are many moving parts to the client build system, but the entry point for
|
||||
most people is the 'client' rule in the Makefile at the root of the Galaxy
|
||||
repository. Execute the following to perform a complete build suitable for
|
||||
repository. Execute the following to perform a complete build suitable for
|
||||
local development, including dependency staging, style building, script
|
||||
processing, and bundling. This is a development-specific build which includes
|
||||
processing, and bundling. This is a development-specific build which includes
|
||||
extra debugging features, and excludes several production optimizations made
|
||||
during the build process.
|
||||
|
||||
@@ -49,276 +48,120 @@ for inspection of live javascript to facilitate debugging, use:
|
||||
Important Note: The Galaxy repository does not include client script artifacts,
|
||||
and these should not be committed.
|
||||
|
||||
## Automatic Rebuilding
|
||||
|
||||
Automatic Rebuilding (Watch Mode)
|
||||
=================================
|
||||
|
||||
When you're actively developing, it is sometimes convenient to have the client
|
||||
automatically rebuild every time you save a file. You can do this using:
|
||||
When you're actively developing, it is convenient to have the client
|
||||
automatically rebuild every time you save a file. You can do this using:
|
||||
|
||||
make client-watch
|
||||
|
||||
This will first stage any dependencies (yarn-installed packages like jquery,
|
||||
etc), and then will watch for changes in any of the galaxy client source files.
|
||||
When a file is changed, the client will automatically rebuild, after which you
|
||||
can usually force refresh your browser to see changes. Note that it is still
|
||||
recommended to run `make client` after you are finished actively developing
|
||||
using `make client-watch`.
|
||||
This will first stage client dependencies, initiate a build, and then will
|
||||
watch for changes in any of the galaxy client source files. When a file is
|
||||
changed, the client will automatically rebuild, after which you can refresh
|
||||
your browser to see changes.
|
||||
|
||||
Note that there's a new, better option described in the next section. This
|
||||
method of building will likely be deprecated as HMR is more widely tested.
|
||||
For even more rapid development you can use the webpack development server,
|
||||
which takes advantage of hot module replacement (HMR). This technique allows
|
||||
swapping out of javascript modules while the application is running without
|
||||
requiring a full page reload most of the time, at least in the more modern
|
||||
parts of the application.
|
||||
|
||||
|
||||
Even Better Automatic Rebuilding (HMR)
|
||||
======================================
|
||||
|
||||
For even more rapid development you can use the webpack development server for
|
||||
Hot Module Replacement (HMR). This technique allows swapping out of modules
|
||||
while the application is running without requiring a full page reload most of
|
||||
the time.
|
||||
|
||||
Setting this up is a little more involved, but it is the fastest possible way
|
||||
to iterate when developing the client. You'll need to start two separate
|
||||
processes here. The first command below starts a special webpack dev server
|
||||
after a client build, and the second starts a Galaxy server like usual, but
|
||||
with extra mappings that redirect client artifact requests to the mentioned
|
||||
webpack dev server.
|
||||
The command below starts a special webpack dev server after a client
|
||||
build.
|
||||
|
||||
make client-dev-server
|
||||
GALAXY_CLIENT_DEV_SERVER=1 sh run.sh
|
||||
|
||||
Note that this only works under uWSGI due to the extra internal routing rules
|
||||
employed. If you're using the older Paste-based galaxy webserver you'll need
|
||||
to swap it over to take advantage of this functionality.
|
||||
This will start up an extra client development server running on port 8081.
|
||||
Open your browser to http://localhost:8081 (instead of the default 8080 that
|
||||
Galaxy would run on), and you should see Galaxy like normal. Except now, when
|
||||
you change client code it'll automatically rebuild *and* reload the relevant
|
||||
portion of the application for you. Note that unlike previous versions of this
|
||||
functionality, it is no longer required to use uWSGI for this. Lastly, if you
|
||||
are running Galaxy at a location other than the default, you can specify a
|
||||
different proxy target (in this example, port 8000) using the GALAXY_URL
|
||||
environment variable:
|
||||
|
||||
GALAXY_URL="http://localhost:8000" make client-dev-server
|
||||
|
||||
Changing Styles/CSS
|
||||
===================
|
||||
Sometimes you want to run your local UI against a remote Galaxy server. This is also possible, if you enable `CHANGE_ORIGIN` flag
|
||||
|
||||
CHANGE_ORIGIN=true GALAXY_URL="https://usegalaxy.org/" make client-dev-server
|
||||
|
||||
## Changing Styles/CSS
|
||||
|
||||
Galaxy uses Sass for its styling, which is a superset of CSS that compiles down
|
||||
to regular CSS. Most Galaxy styling source (.scss) files are kept in
|
||||
`client/galaxy/style/scss. There are additionally style blocks alongside some
|
||||
Vue components -- styles that are particular to that individual component and
|
||||
do not apply site-wide.
|
||||
to regular CSS. Most Galaxy styling source (.scss) files are kept in
|
||||
`client/src/style/scss. There are additionally style blocks alongside some Vue
|
||||
components -- styles that are particular to that individual component and do
|
||||
not apply site-wide.
|
||||
|
||||
On build, the compiled css bundle is served at `/static/style/base.css`.
|
||||
|
||||
As mentioned above, `make client` will rebuild styles, as a part of the webpack
|
||||
build. For iterative development, "Watch Mode" rebuilds as described above do
|
||||
build. For iterative development, "Watch Mode" rebuilds as described above do
|
||||
include style changes.
|
||||
|
||||
|
||||
# Client-Side Unit Testing
|
||||
## Client-Side Unit Testing
|
||||
|
||||
Galaxy's client is undergoing an extensive refactoring and modernizing process.
|
||||
As part of this initiative, we would like to request that all new client-side
|
||||
code submissions come with accompanying javascript unit-tests for the
|
||||
developer-facing API of your new code.
|
||||
|
||||
## Testing Technologies
|
||||
### Testing Technologies
|
||||
|
||||
[Galaxy uses Mocha](https://mochajs.org/) for its client-side unit testing
|
||||
framework with [Chai as its assertion library](https://www.chaijs.com/) and
|
||||
[karma as a test runner](https://karma-runner.github.io/latest/index.html).
|
||||
The karma configs are contained in the client/karma folder. Unit tests are run
|
||||
using Chrome headless by default.
|
||||
[Galaxy uses Jest](https://jestjs.io/) for its client-side unit testing
|
||||
framework.
|
||||
|
||||
For testing Vue components, we use the [Vue testing
|
||||
utils](https://vue-test-utils.vuejs.org/) to mount individual components in a
|
||||
test bed and check them for rendered features.
|
||||
test bed and check them for rendered features. Please use jest-based mocking
|
||||
for isolating test functionality.
|
||||
|
||||
We use the [babel plugin
|
||||
Rewire](https://github.com/speedskater/babel-plugin-rewire) to mock imported
|
||||
ES6 dependencies during unit-testing. [Sinon](https://sinonjs.org/) is also
|
||||
available for more robust stubbing, mocking and spying utilities.
|
||||
A set of older qUnit tests also exist which will be phased-out as the code they
|
||||
support is replaced with modern component-based implementations. In the
|
||||
meantime, we still run the qunit tests in sequence.
|
||||
|
||||
A set of older qUnit tests also exist which will likely be phased-out as the
|
||||
code they support is replaced with modern component-based implementations. In
|
||||
the meantime, karma runs both the mocha and qunit tests in sequence.
|
||||
### Running the tests
|
||||
|
||||
#### At Build-Time
|
||||
|
||||
## Running the tests
|
||||
|
||||
### At Build-Time
|
||||
To simply run all the javascript unit tests, you can use make from the root
|
||||
directory. This is what happens during a complete client build.
|
||||
|
||||
make client-test
|
||||
|
||||
|
||||
### During Development
|
||||
#### During Development
|
||||
|
||||
During client-side development, it is more convenient to have granular testing
|
||||
options. The various testing scripts are defined inside package.json within the
|
||||
client folder, and are called either with `yarn` as demonstrated in the
|
||||
client folder, and are called with `yarn` as demonstrated in the
|
||||
following commands.
|
||||
|
||||
#### Run all tests (mocha and qunit):
|
||||
This is what CI is going to run, and also what 'make client-test' invokes,
|
||||
executing all the client tests:
|
||||
|
||||
yarn run test
|
||||
|
||||
#### Watch and rerun all client-side unit-tests every time a source file changes:
|
||||
You can also bypass qunit and single-run all of the jest tests like so:
|
||||
|
||||
yarn run test-watch
|
||||
yarn run jest
|
||||
|
||||
#### Run only specified test files when a source file changes:
|
||||
Or, if you really want to run just the qunit tests:
|
||||
|
||||
yarn run test-watch watch-only="Tags/*.test.js"
|
||||
yarn run qunit
|
||||
|
||||
(The above watch-only parameter will be mapped to the following glob expression "**/Tags/*.test.js")
|
||||
##### Watch and rerun jest unit tests every time a source file changes
|
||||
|
||||
#### Run qunit legacy tests
|
||||
This is incredibly handy, and there are a host of options in the interactive
|
||||
terminal this starts for executing Jest tests.
|
||||
|
||||
yarn run test-qunit
|
||||
yarn run jest-watch
|
||||
|
||||
##### Run only specified test files when a source file changes
|
||||
|
||||
## Writing a test file
|
||||
yarn run jest-watch MyModule
|
||||
|
||||
The karma configs are setup to look at any file ending in "*.test.js". Please
|
||||
place your test files inside client/galaxy/scripts folders right next to
|
||||
whatever files that they are testing.
|
||||
yarn run jest-watch Dialog
|
||||
|
||||
```javascript
|
||||
// yourtestfile.test.js
|
||||
|
||||
import { things } from "./yourtestfile.js";
|
||||
|
||||
describe("some module you wrote", () => {
|
||||
|
||||
let transientVariables, serviceInstances, testData;
|
||||
|
||||
beforeEach(() => {
|
||||
// setup your code (if necessary)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// teardown your code (so it doesn't ruin the next test)
|
||||
})
|
||||
|
||||
it("should do something or other", () => {
|
||||
assert(somethingThatShouldTrue, "explain what went wrong");
|
||||
expect(something).to.eq(true);
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
## Testing ~~Suggestions~~ Obligations
|
||||
|
||||
|
||||
### Clearly document the intent of your test
|
||||
|
||||
Please remember that these tests are not *for* you. They're for the people who
|
||||
come after you. It will be a lot easier to modify, repair and upgrade your code
|
||||
if they can figure out what you were originally hoping to accomplish.
|
||||
|
||||
Add a couple of comments. Use variable names that mean something. Use the
|
||||
assertion failure description parameters when possible. Nobody's code is as
|
||||
self-documenting as they believe it to be.
|
||||
|
||||
```javascript
|
||||
|
||||
// NOT AWESOME
|
||||
// this test forces the next victim to have to
|
||||
// read every single line of source code you wrote
|
||||
it("should work", async () => {
|
||||
let thing = await svc.loadHistories();
|
||||
assert(thing);
|
||||
})
|
||||
|
||||
// BETTER
|
||||
// With this test, you can just read at the errors on the mocha
|
||||
// test output to have a pretty good idea of what went sour.
|
||||
it("should have resolved to an array of integer IDs", async () => {
|
||||
let historyIds = await historyService.loadHistories();
|
||||
assert(historyIds, "History service should have had a result");
|
||||
assert(historyIds instanceof Array, "History results should have been an array");
|
||||
assert(historyIds.length == 4, "History call should have returned 4 ids");
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Only test the public API that you define (carefully!)
|
||||
|
||||
Internal implementations come and go with library upgrades and new tech. But
|
||||
the point of the unit test is to make sure your units work as designed....
|
||||
which means you need to... you know... design your code to work in units.
|
||||
|
||||
Separate your concerns and identify the developer-facing methods and functions
|
||||
you expect them to use. Test THOSE. Everything else should probably be
|
||||
considered an implementation detail.
|
||||
|
||||
Assume nobody cares *how* your code works, we just need to know that the public
|
||||
API you designed *does* work. If performance problems or new tech necessitate a
|
||||
re-write, these tests become a guide for the next implementation.
|
||||
|
||||
|
||||
### Wrap native browser resources in a function so they can be easily mocked
|
||||
|
||||
If your javascript needs to talk to the window object, or navigator, etc. wrap
|
||||
that in a function call so that it can be easily mocked during testing.
|
||||
|
||||
```javascript
|
||||
|
||||
// myModule.js
|
||||
|
||||
// ... other code
|
||||
|
||||
export function redirectTo(url) {
|
||||
window.location = url;
|
||||
}
|
||||
|
||||
|
||||
// myModule.test.js
|
||||
|
||||
import { __RewireAPI__ as myModuleRewire} from "./myModule";
|
||||
|
||||
function fakeRedirect(url) {
|
||||
console.log(`I would have gone to: ${url}`);
|
||||
}
|
||||
|
||||
describe("some module", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
myModuleRewire.__Rewire__("redirectTo", fakeRedirect);
|
||||
})
|
||||
|
||||
// ....
|
||||
})
|
||||
```
|
||||
|
||||
### Implement logic in pure functions when possible
|
||||
|
||||
The more of your logic that is written in deterministic functions (i.e. no
|
||||
side-effects, same inputs always result in same outputs) the easier it is to
|
||||
test. Just load up the functions and supply suitable test inputs.
|
||||
|
||||
There is almost definitely no such thing as a well-written 1000 line function.
|
||||
Most of whatever happened in that thing was probably deterministic and can be
|
||||
broken up into easily testable chunks.
|
||||
|
||||
|
||||
## Specific test scenarios & examples
|
||||
|
||||
[Mocking an imported dependency](https://github.com/galaxyproject/galaxy/blob/dev/client/galaxy/scripts/components/Tags/tagService.test.js)
|
||||
|
||||
[Testing async operations](https://github.com/galaxyproject/galaxy/blob/dev/client/galaxy/scripts/components/Tags/tagService.test.js)
|
||||
|
||||
[Testing a Vue component for expected rendering output](https://github.com/galaxyproject/galaxy/blob/dev/client/galaxy/scripts/components/Tags/StatelessTags.test.js)
|
||||
|
||||
[Firing an event against a shallow mounted vue component](https://github.com/galaxyproject/galaxy/blob/dev/client/galaxy/scripts/components/Tags/StatelessTags.test.js)
|
||||
|
||||
|
||||
## The dirty secret about testing
|
||||
|
||||
It's good to have tests, but testing code isn't really about testing at all,
|
||||
it's actually about software design.
|
||||
|
||||
Maintainable software is testable software. If you can run a unit test on your
|
||||
code, then that means you must have necessarily separated your code into
|
||||
testable units and you will have almost definitely written better, more
|
||||
modular, more easily manipulated code, and nobody will ever contemplate using
|
||||
git-blame to figure out what went wrong.
|
||||
|
||||
Probably.
|
||||
yarn run jest-watch workflow/run
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"presets": ["@babel/preset-env"],
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": ["@babel/plugin-transform-runtime"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"name": "galaxy-client-libs",
|
||||
"version": "0.0.0",
|
||||
"description": "External client-side libraries used by Galaxy",
|
||||
"keywords": [
|
||||
"galaxy",
|
||||
"galaxyproject"
|
||||
],
|
||||
"homepage": "usegalaxy.org",
|
||||
"dependencies": {
|
||||
"farbtastic": "~2.0.0-alpha.1",
|
||||
"jquery-form": "~3.46.0",
|
||||
"jquery-autocomplete": "git://github.com/dyve/jquery-autocomplete",
|
||||
"select2": "~3.5.2",
|
||||
"jStorage": "~0.4.12",
|
||||
"dynatree": "~1.2.5",
|
||||
"wymeditor": "~1.0.0-rc.1",
|
||||
"jstree": "~3.0.9",
|
||||
"jquery-ui": "git://github.com/jquery/jquery-ui.git#~1.11.2",
|
||||
"threedubmedia.jquery.event": "*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
Without a doubt. The most problematic part of the old client is the way every important piece of
|
||||
information was hung on a global variable whose initialization is completely unregulated.
|
||||
|
||||
### Don't directly reference window.Galaxy in Vue components
|
||||
|
||||
Components take props. Please pass in any values you might need from window.Galaxy as props and
|
||||
avoid referencing global Galaxy inside your components. I've even created basic providers which give
|
||||
you access to the Galaxy.config, current user, and current user histories. Please use them to
|
||||
retrieve your values, and bypass importing Galaxy altogether.
|
||||
|
||||
#### Sometimes you still need to update Vue from backbone as the legacy environment changes
|
||||
There are definitely use-cases where the Backbone models update over time and we need to update some
|
||||
value inside Vue. Instead of importing backbone models directly into Vue components, try building a
|
||||
backbone event listener that updates some relevant Vuex store.
|
||||
|
||||
* [Keeping Vuex in Sync with
|
||||
Galaxy](https://github.com/galaxyproject/galaxy/blob/dev/client/src/store/syncVuexToGalaxy.js)
|
||||
|
||||
These issues should disappear over time as the all of the old client is rebuilt in the new
|
||||
ecosystem.
|
||||
|
||||
|
||||
## Mount Functions
|
||||
|
||||
In what most people think of as a "standard" Vue application there would be only one place that Vue
|
||||
is mounted to the HTML environment, and that would be in a main.j or an app.js. Most modern
|
||||
single-page applications only have one starting point like that.
|
||||
|
||||
However, we are incrementally replacing old Backbone views, so in its current state, Galaxy may have
|
||||
several mounting functions for various components depending on where that component is intended to
|
||||
fit into the existing Backbone layouts.
|
||||
|
||||
|
||||
### Using the standard mount to pass in Galaxy variables as props
|
||||
|
||||
A standard mount function has been provided in src/utils. This mount function accepts a component
|
||||
definition, and then allows you to start up your Vue component with our standard load-out of plugins
|
||||
including localization, Vuex, and a couple other utilities. This is the preferred way to mount your
|
||||
component inside the old Backbone layout until the application is fully converted.
|
||||
|
||||
```js static
|
||||
// src/mvc/OldBackboneView.js
|
||||
|
||||
import { getGalaxyInstance } from "app";
|
||||
import MyComponent from "components/MyComponent";
|
||||
import { mountVueComponent } from "utils/mountVueComponent";
|
||||
|
||||
const OldBackboneView = {
|
||||
|
||||
someInitMethodYouMake() {
|
||||
const Galaxy = getGalaxyInstance();
|
||||
const mounter = mountVueComponent(MyComponent);
|
||||
|
||||
// pass in required props
|
||||
const props = {
|
||||
|
||||
// Something peeled off the global galaxy
|
||||
somePropVal: Galaxy.someDealie,
|
||||
|
||||
// ...or the current history
|
||||
name: Galaxy.currentHistory.name,
|
||||
|
||||
// or maybe from the backbone model for this view
|
||||
shoeSize: this.model.shoeSize
|
||||
};
|
||||
|
||||
// VM is a Vue instance.
|
||||
// this.$el is some jquery selection, first item is the actual DOM object
|
||||
const container = this.$el[0];
|
||||
const vm = mounter(props, container);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
Did you know, jQuery is old enough to drive? It's old enough to get a driver's license. jQuery is a
|
||||
tool that was built to deal with inconsistencies in browsers that NO LONGER EXIST. In a couple
|
||||
years, jQuery will be voting, drinking, and capable of being tried as an adult.
|
||||
|
||||
If you think you need jQuery, you are mistaken. Please seek help from somebody in the wg-ui-ux
|
||||
workgroup. There is nothing jQuery can provide you that isn't already part of vanilla javascript or
|
||||
a standard well-tested 3rd party modern npm module.
|
||||
|
||||
But that's not even the main problem. jQuery injects global initializations into every page on the
|
||||
site whether you want it or not. jQuery leverages an outdated initialization paradigm which is
|
||||
hugely problematic when it comes to unit testing and module building.
|
||||
|
||||
One of our most important goals in redesigning Galaxy is the complete elimination of this library
|
||||
from our source, along with all its invasive plugins.
|
||||
|
||||
### References
|
||||
* [You Don't Need jQuery](https://github.com/nefe/You-Dont-Need-jQuery)
|
||||
* [document.querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
|
||||
@@ -0,0 +1,164 @@
|
||||
We are using components in two very distinct ways. The first, "normal", kind of component will
|
||||
probably look familiar to anybody whis is already passingly familiar with Vue. Here the relevant
|
||||
information comes in as properties, any internal variables get defined in "data", changes go out as
|
||||
events.
|
||||
|
||||
### Composition Example
|
||||
|
||||
```html static
|
||||
<!-- Use of a renderless component with a display component -->
|
||||
<DoodadProvider v-slot="{ doodad, saveDoodad }">
|
||||
<DoodadEditor :doodad="doodad" @update:doodad="saveDoodad" />
|
||||
</DoodadProvider>
|
||||
```
|
||||
|
||||
In this example, we've created a component whose job is to deal with loading and updating the doodad
|
||||
object. Notice that there is no markup inside the DoodadProvider other than the explicit renderless
|
||||
component we previously made, but you are free to putput whatever you want in there, accessing the
|
||||
doodad and saveDoddad properties as desired, as well as any other local data with the only
|
||||
restriction that Vue needs a single root element in which to render.
|
||||
|
||||
|
||||
## The Renderer
|
||||
|
||||
```html static
|
||||
<!-- DoodadEditor.vue, a simple "rendering" component -->
|
||||
|
||||
<template>
|
||||
<AutoComplete
|
||||
:options="options"
|
||||
:value="doodad.category"
|
||||
@select="saveCategory"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: {
|
||||
doodad: { type: Object, required: true },
|
||||
options: { type: Array, required: true },
|
||||
},
|
||||
methods: {
|
||||
saveCategory(newCategory) {
|
||||
this.$emit('update:doodad', { ...this.doodad, category: newCategory });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
This component accepts a mandatory input object (doodad), lets the user play with a category prop,
|
||||
then emits a fresh object after it's done. So what, what's the big deal? The important part to walk
|
||||
away from this dumb example is the things that are NOT in this sample component.
|
||||
|
||||
This component doesn't save the data. This component doesn't make ajax calls, and this component
|
||||
doesn't mutate its props. What it does do is to allow the user to edit some object named "doodad"
|
||||
and emits a new fresh version of that doodad when it's done. (Note also that we are using the
|
||||
update:propname event syntax whenever possible [to facilitate .sync
|
||||
binds](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier)).
|
||||
|
||||
Whatever happens to that new object is somebody else's job. As soon as you tie the data management
|
||||
to the rendering, the re-usability of your components craters.
|
||||
|
||||
|
||||
## The Provider
|
||||
|
||||
As the opposite of the rendering component, a provider or renderless component, is pure logic. It
|
||||
should not know or care what your renderer is going to do with the data it provides. It is simply a
|
||||
fancy way of configuring some data manipulation methods. This is one of the many ways of reusing
|
||||
functionality available in Vue. Some others are [Mixins](https://vuejs.org/v2/guide/mixins.html),
|
||||
[Provide/Inject](https://v3.vuejs.org/guide/component-provide-inject.html) and (in Vue3) [the
|
||||
composition API](https://v3.vuejs.org/guide/composition-api-introduction.html).
|
||||
|
||||
|
||||
```js static
|
||||
// DoodadProvider.js
|
||||
|
||||
import { loadDoodad, saveDoodad } from "./someAjaxQueryModule";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loaded: false,
|
||||
doodad: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async saveDoodad(newVal) {
|
||||
this.loaded = false;
|
||||
const newVal = await saveDoodad(newVal);
|
||||
this.doodad = newVal;
|
||||
this.loaded = true;
|
||||
},
|
||||
async loadDoodad(newVal) {
|
||||
this.loaded = false;
|
||||
const newVal = await loadDoodad(newVal);
|
||||
this.loaded = true;
|
||||
return newVal;
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.doodad = await loadDoodad();
|
||||
},
|
||||
render() {
|
||||
return return this.$scopedSlots.default({
|
||||
loaded: this.loaded,
|
||||
doodad: this.doodad,
|
||||
saveDoodad: this.saveDoodad
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here is an example of a simple possible renderless provider. The important part about this is the
|
||||
render() function which simply renders [one big default
|
||||
slot](https://vuejs.org/v2/guide/components-slots.html) and binds some of its own properties to that
|
||||
slot for use by downstream components.
|
||||
|
||||
## Unit Testing a renderless component
|
||||
|
||||
Testing of a component like our editor is pretty straightforward and follows the standard Vue
|
||||
guidelines. If you did a clean-enough job you won't even need to mock anything since all your data
|
||||
dependencies should be delivered via props.
|
||||
|
||||
But it's not so obvious how to unit-test a renderless provider. What do you check for? There's no
|
||||
mandatory markup, just one big empty slot.
|
||||
|
||||
```js static
|
||||
// Testing a renderless component
|
||||
|
||||
import { shallowMount } from "@vue/test-utils";
|
||||
import { getLocalVue, waitForLifecyleEvent } from "jest/helpers";
|
||||
import DoodadProvider from "./DoodadProvider";
|
||||
|
||||
describe("A renderless component", () => {
|
||||
const localVue = getLocalVue();
|
||||
let wrapper;
|
||||
let slotProps;
|
||||
|
||||
beforeEach(async () => {
|
||||
wrapper = shallowMount(DoodadProvider, {
|
||||
localVue,
|
||||
// The mount fn allows you to hook into a slot for this very reason
|
||||
scopedSlots: {
|
||||
default(props) {
|
||||
slotProps = props;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// waits for "updated" Vue lifecycle hook to fire on the renderless
|
||||
// component. This is often good enough for waiting for
|
||||
// an initial ajax load to finish, for example
|
||||
await waitForLifecyleEvent(wrapper.vm, "updated");
|
||||
})
|
||||
|
||||
test("someProp", () => {
|
||||
const { someProp } = slotProps;
|
||||
expect(someProp).toExist();
|
||||
// ...more tests
|
||||
})
|
||||
})
|
||||
```
|
||||
@@ -0,0 +1,71 @@
|
||||
### A component is really just a fancy function
|
||||
|
||||
I'm not talking about how webpack turns it into a rendering function. That's obvious.
|
||||
|
||||
I mean conceptually, props come in (like arguments) and events go out (like the return statements).
|
||||
A component is a fancy kind of function that can keep emitting results and accept changing inputs
|
||||
over time. In truth it more closely resembles an Observable, but an observable is ALSO a slightly
|
||||
fancier kind of function.
|
||||
|
||||
If you just think of a component as thing that takes input props and emits output events you're well
|
||||
on your way to using them well.
|
||||
|
||||
The worst components are ones that might as well just be a big single page script. That's zero
|
||||
percent better than the spaghetti we're working so hard to replace. That's just repackaging all the
|
||||
problems of the old imperative class-based legacy code.
|
||||
|
||||
### Get comfortable with events, limit your dependence on Vuex
|
||||
|
||||
New vue programmers are ok at handing props to components, but they rarely use events effectively
|
||||
(at first). As a result they end up using a lot of global state, a million little data props and
|
||||
relying on imperfect globalized tools like Vuex or other imported dependencies for every little
|
||||
variable.
|
||||
|
||||
Vuex definitely has its uses, but not as many as you might expect given the way it is
|
||||
overly-emphasized in common tutorials. It's easy to walk away from an "Intro to Vue" video with the
|
||||
idea that all data must live in Vuex all the time. That's a really undesirable situation.
|
||||
|
||||
Although vuex is a well-organized (many would say over-organized) state machine, it is important
|
||||
to remember that it is still a kind of global injection and deserves to be considered as such.
|
||||
|
||||
* [Should I Store This Data in
|
||||
Vuex](https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/)
|
||||
* [Vuex getters are great, but don’t overuse
|
||||
them](https://codeburst.io/vuex-getters-are-great-but-dont-overuse-them-9c946689b414)
|
||||
|
||||
Data persistence should be something that happens near the top of your component tree, not down in
|
||||
the guts.
|
||||
|
||||
Your first thought with a component should be: "How can I offload the handling of the results of
|
||||
this component to my caller?" The answer is usually going to be events. A component that simply
|
||||
accepts props and emits events can be re-used in more contexts than one that relies on an external
|
||||
global state to operate.
|
||||
|
||||
#### Read up on .sync and v-model
|
||||
|
||||
They're just fancy shorthands for a prop / event handler combination. They are fundamentally no
|
||||
different from props and events, but the syntax is important to understand.
|
||||
|
||||
|
||||
### Think carefully about what should really be in "data".
|
||||
|
||||
Most of good component design boils down to answering the following question: What do I want to put
|
||||
in data, computed, and props?
|
||||
|
||||
Data is the place where temp data goes that is not sensible to persist in Vuex or other
|
||||
application-wide global state, usually because its use is very specific to the operation of this
|
||||
particular component. There really should only be a few variables in data.
|
||||
|
||||
#### Break down your own internal dependencies
|
||||
|
||||
Most components only need one or two variables in data. If you have a large amount of data
|
||||
variables, it's worth taking a little time to stop and build a mini-dependency tree for yourself.
|
||||
You will probably find that almost everything can be written in terms of computed transformations on
|
||||
a small number of data and properties.
|
||||
|
||||
Defining your values using computes will lead to a lot less "oh I forgot to update that
|
||||
variable"-style bugs.
|
||||
|
||||
If you have more than a few data variables you probably (a) aren't leveraging computeds and
|
||||
properties, or (b) are trying to implement too many features for just one component. It is important
|
||||
separate your concerns in components just like you do in any other kind of programming.
|
||||
@@ -0,0 +1,76 @@
|
||||
### ...in VSCode
|
||||
|
||||
There's a bunch of "how to debug javascript in vscode" cookbooks out there for the googling, but
|
||||
most of them don't bother explaining all the gotchas and what each of the cryptic configuration
|
||||
parameters actually does.
|
||||
|
||||
I've gone ahead and annotated all the options, hopefully this will save some time, at least until VS
|
||||
code updates its test extensions again.
|
||||
|
||||
#### To debug a single Jest test:
|
||||
|
||||
1. Open a jest test (a file that ends with *.test.js)
|
||||
|
||||
1. Make sure the test file is selected, especially if you have multiple files open. This process
|
||||
will fail confusingly and without obvious error if you have not launched the debugger with the
|
||||
actual Jest test file selected, and it's easy to accidentally click into another file if you've
|
||||
got a dozen open.
|
||||
|
||||
1. Place a breakpoint in the margin of the file. You can place breakpoints anywhere in your source,
|
||||
but you must launch the debugger while the jest file is selected because that is where jest and
|
||||
webpack will start compiling. Alternatively, you can manually override the selected file in the
|
||||
configuration definition, like if you're testing the same file over and over again and don't want
|
||||
to worry about selecting it.
|
||||
|
||||
1. Update your .vscode/launch.json file to include the following launch configuration. If you don't
|
||||
have a .vscode folder, you can just make one, but my experience is this all works better if you
|
||||
have explicitly saved your VSCode project into a workspace rather than just using "code ." from a
|
||||
terminal. Doing so will have initialized the .vscode folder already.
|
||||
|
||||
1. Click on the "Run and Debug" tab from the vscode icons on the left and choose the sample launch
|
||||
configuration (defined below) from the dropdown "run and debug". Or just hit F5.
|
||||
|
||||
1. Wait a bit, for webpack to compile everything, eventually you should be able to hover over
|
||||
variables near your breakpoint and see their values in the "Variables" section of the Run and
|
||||
Debug pane.
|
||||
|
||||
|
||||
|
||||
```json
|
||||
// sample launch.json
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"name": "debug selected jest test",
|
||||
"request": "launch",
|
||||
|
||||
// launches version of jest from inside the node_modules
|
||||
// this means you need to have run yarn first
|
||||
"program": "${workspaceFolder}/client/node_modules/jest/bin/jest",
|
||||
"args": [
|
||||
// Alias -i.
|
||||
// Normally jest opens up a bunch of workers to run all your tests faster
|
||||
// but we don't want that right now.
|
||||
"--runInBand",
|
||||
|
||||
// finds jest config
|
||||
"--config",
|
||||
"${workspaceFolder}/client/tests/jest/jest.config.js",
|
||||
|
||||
// This is how vscode references the currently selected file
|
||||
"${file}"
|
||||
],
|
||||
"cwd": "${workspaceFolder}/client",
|
||||
|
||||
// opens jest output in integrated terminal
|
||||
"console": "integratedTerminal",
|
||||
|
||||
// allows you to place breakpoints right in vscode's gutter
|
||||
"disableOptimisticBPs": true,
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
[Galaxy uses Jest](https://jestjs.io/) for its client-side unit testing
|
||||
framework.
|
||||
|
||||
For testing Vue components, we use the [Vue testing
|
||||
utils](https://vue-test-utils.vuejs.org/) to mount individual components in a
|
||||
test bed and check them for rendered features. Please use jest-based mocking
|
||||
for isolating test functionality.
|
||||
|
||||
|
||||
### Specific test scenarios & examples
|
||||
|
||||
* [Mocking an imported
|
||||
dependency](https://github.com/galaxyproject/galaxy/blob/dev/client/src/components/Tags/tagService.test.js)
|
||||
* [Testing async
|
||||
operations](https://github.com/galaxyproject/galaxy/blob/dev/client/src/components/Tags/tagService.test.js)
|
||||
* [Testing a Vue component for expected rendering
|
||||
output](https://github.com/galaxyproject/galaxy/blob/dev/client/src/components/Tags/StatelessTags.test.js)
|
||||
* [Firing an event against a shallow mounted vue
|
||||
component](https://github.com/galaxyproject/galaxy/blob/dev/client/src/components/Tags/StatelessTags.test.js)
|
||||
@@ -0,0 +1,59 @@
|
||||
Part of making good code is making that code easy to test.
|
||||
|
||||
### Implement logic in pure functions when possible
|
||||
|
||||
The more of your logic that is written in deterministic functions (i.e. no
|
||||
side-effects, same inputs always result in same outputs) the easier it is to
|
||||
test. Just load up the functions and supply suitable test inputs.
|
||||
|
||||
There is almost definitely no such thing as a well-written 1000 line function.
|
||||
Most of whatever happened in that thing was probably deterministic and can be
|
||||
broken up into easily testable chunks.
|
||||
|
||||
|
||||
### Wrap native browser resources in a function so they can be easily mocked
|
||||
|
||||
If your javascript needs to talk to the window object, or navigator, etc. wrap
|
||||
that in a function call so that it can be easily mocked during testing.
|
||||
|
||||
|
||||
#### Your Module
|
||||
```js static
|
||||
// myModule.js
|
||||
|
||||
// ... other code
|
||||
|
||||
export function redirectTo(url) {
|
||||
window.location = url;
|
||||
}
|
||||
|
||||
export function theThingYouReallyCareAbout() {
|
||||
.....
|
||||
redirectTo(somePlace);
|
||||
....
|
||||
}
|
||||
```
|
||||
|
||||
#### Your test file
|
||||
```js static
|
||||
// myModule.test.js
|
||||
import { theThingYouReallyCareAbout, redirectTo } from "./myModule";
|
||||
|
||||
// calling jest.mock on the appropriate import path wraps the exports and gives
|
||||
// access to new testing methods like mockImplementation
|
||||
jest.mock("./myModule");
|
||||
redirectTo.mockImplementation((url) => {
|
||||
console.log(`I would have gone to: ${url}`);
|
||||
});
|
||||
|
||||
// You are testing theThingYouReallyCareAbout, but that function needs
|
||||
// to call a window.relocate, By wrapping redirectTo as a function it was easy to mock
|
||||
// and avoid errors in your test, because native browser objects do not even exist
|
||||
// in the unit-testing environment.
|
||||
describe("theThingYouReallyCareAbout", () => {
|
||||
it("Performs a redirect when Foo is clicked"){
|
||||
const result = theThingYouReallyCareAbout(abc123);
|
||||
expect(result).toBe(1);
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
### Clearly document the intent of your test
|
||||
|
||||
Please remember that these tests are not _for_ you. They're for the people who
|
||||
come after you. It will be a lot easier to modify, repair and upgrade your code
|
||||
if they can figure out what you were originally hoping to accomplish. Try to
|
||||
use as detailed 'expect' statements as possible -- overuse of 'toBeTruthy()'
|
||||
for example, can hide the intent of your test.
|
||||
|
||||
Add a couple of comments. Use variable names that mean something. Nobody's
|
||||
code is as self-documenting as they believe it to be.
|
||||
|
||||
|
||||
### Only test the public API that you define
|
||||
|
||||
Internal implementations come and go with library upgrades and new tech. But
|
||||
the point of the unit test is to make sure your units work as designed....
|
||||
which means you need to... you know... design your code to work in units.
|
||||
|
||||
Separate your concerns and identify the developer-facing methods and functions
|
||||
you expect them to use. Test THOSE. Everything else should probably be
|
||||
considered an implementation detail.
|
||||
|
||||
The other side of the same coin is to test *only* the unit in question. If your
|
||||
component has a model that uses a service that touches Vuex, which then uses
|
||||
Axios to fetch some data -- don't test all that at once. Break things apart and
|
||||
mock functionality to isolate testing to units. End to end testing is a
|
||||
separate thing that shouldn't be attempted using spec tests in Jest.
|
||||
|
||||
Assume nobody cares _how_ your code works, we just need to know that the public
|
||||
API you designed _does_ work. If performance problems or new tech necessitate a
|
||||
re-write, these tests become a guide for the next implementation.
|
||||
|
||||
|
||||
### Writing a test file
|
||||
|
||||
Jest will try to test any file ending in "\*.test.js". Please place your test
|
||||
files inside client/src folders right next to whatever files that they are
|
||||
testing.
|
||||
|
||||
Jest has extensive documentation on the expect API, mocking, and more on the
|
||||
[official docs page](https://jestjs.io/docs/en/getting-started.html), which will
|
||||
be your best resource here.
|
||||
|
||||
```js static
|
||||
// yourcode.test.js
|
||||
|
||||
import { things } from "./yourcode.js";
|
||||
|
||||
describe("some module you wrote", () => {
|
||||
let transientVariables;
|
||||
let serviceInstances;
|
||||
let testData;
|
||||
|
||||
beforeEach(() => {
|
||||
// setup your code (if necessary)
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// teardown your code (so it doesn't ruin the next test)
|
||||
});
|
||||
|
||||
it("should do something or other", () => {
|
||||
expect(workflowNodeCount()).toBe(5);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
### Check out the Jest helper functions
|
||||
|
||||
We have created some [common helpers for common testing
|
||||
scenarios](https://github.com/galaxyproject/galaxy/blob/dev/client/tests/jest/helpers.js).
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export default {
|
||||
name: "development configs"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default {
|
||||
name: "production configs"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export default {
|
||||
name: "unit testing configs",
|
||||
testBuild: true,
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
The \*.md files in this directory are rendered as a style guide generated when
|
||||
running ```yarn run styleguide```.
|
||||
|
||||
For more details see [Vue
|
||||
Styleguidist](https://github.com/vue-styleguidist/vue-styleguidist).
|
||||
@@ -1,379 +0,0 @@
|
||||
## Buttons
|
||||
|
||||
Regular buttons
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<button type="button" class="btn btn-primary">Primary</button>
|
||||
<button type="button" class="btn btn-secondary">Secondary</button>
|
||||
<button type="button" class="btn btn-success">Success</button>
|
||||
<button type="button" class="btn btn-info">Info</button>
|
||||
<button type="button" class="btn btn-warning">Warning</button>
|
||||
<button type="button" class="btn btn-danger">Danger</button>
|
||||
<button type="button" class="btn btn-link">Link</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
Disabled
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<button type="button" class="btn btn-primary disabled">Primary</button>
|
||||
<button type="button" class="btn btn-secondary disabled">Secondary</button>
|
||||
<button type="button" class="btn btn-success disabled">Success</button>
|
||||
<button type="button" class="btn btn-info disabled">Info</button>
|
||||
<button type="button" class="btn btn-warning disabled">Warning</button>
|
||||
<button type="button" class="btn btn-danger disabled">Danger</button>
|
||||
<button type="button" class="btn btn-link disabled">Link</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<button type="button" class="btn btn-outline-primary">Primary</button>
|
||||
<button type="button" class="btn btn-outline-secondary">Secondary</button>
|
||||
<button type="button" class="btn btn-outline-success">Success</button>
|
||||
<button type="button" class="btn btn-outline-info">Info</button>
|
||||
<button type="button" class="btn btn-outline-warning">Warning</button>
|
||||
<button type="button" class="btn btn-outline-danger">Danger</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
|
||||
<button type="button" class="btn btn-primary">Primary</button>
|
||||
<div class="btn-group" role="group">
|
||||
<button id="btnGroupDrop1" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
|
||||
<div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
|
||||
<button type="button" class="btn btn-success">Success</button>
|
||||
<div class="btn-group" role="group">
|
||||
<button id="btnGroupDrop2" type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
|
||||
<div class="dropdown-menu" aria-labelledby="btnGroupDrop2">
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
|
||||
<button type="button" class="btn btn-info">Info</button>
|
||||
<div class="btn-group" role="group">
|
||||
<button id="btnGroupDrop3" type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
|
||||
<div class="dropdown-menu" aria-labelledby="btnGroupDrop3">
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="btn-group" role="group" aria-label="Button group with nested dropdown">
|
||||
<button type="button" class="btn btn-danger">Danger</button>
|
||||
<div class="btn-group" role="group">
|
||||
<button id="btnGroupDrop4" type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></button>
|
||||
<div class="dropdown-menu" aria-labelledby="btnGroupDrop4">
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
<a class="dropdown-item" href="javascript:void(0)">Dropdown link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<button type="button" class="btn btn-primary btn-lg">Large button</button>
|
||||
<button type="button" class="btn btn-primary">Default button</button>
|
||||
<button type="button" class="btn btn-primary btn-sm">Small button</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Alerts
|
||||
|
||||
```vue
|
||||
<div class="alert alert-dismissable alert-warning">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<h4>Warning!</h4>
|
||||
<p>Best check yo self, you're not looking too good. Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, <a href="javascript:void(0)" class="alert-link">vel scelerisque nisl consectetur et</a>.</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="alert alert-dismissable alert-danger">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Oh snap!</strong> <a href="javascript:void(0)" class="alert-link">Change a few things up</a> and try submitting again.
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="alert alert-dismissable alert-success">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Well done!</strong> You successfully read <a href="javascript:void(0)" class="alert-link">this important alert message</a>.
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="alert alert-dismissable alert-info">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong>Heads up!</strong> This <a href="javascript:void(0)" class="alert-link">alert needs your attention</a>, but it's not super important.
|
||||
</div>
|
||||
```
|
||||
|
||||
## Badges
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<span class="badge badge-primary">Primary</span>
|
||||
<span class="badge badge-secondary">Secondary</span>
|
||||
<span class="badge badge-success">Success</span>
|
||||
<span class="badge badge-warning">Warning</span>
|
||||
<span class="badge badge-danger">Danger</span>
|
||||
<span class="badge badge-info">Info</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
```vue
|
||||
<div class="">
|
||||
<ul class="nav nav-pills">
|
||||
<li class="active"><a href="javascript:void(0)">Home <span class="badge">42</span></a></li>
|
||||
<li><a href="javascript:void(0)">Profile <span class="badge-pill"></span></a></li>
|
||||
<li><a href="javascript:void(0)">Messages <span class="badge-pill">3</span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Tables
|
||||
|
||||
```vue
|
||||
<div class="">
|
||||
<table class="table table-striped table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Column heading</th>
|
||||
<th>Column heading</th>
|
||||
<th>Column heading</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr class="table-success">
|
||||
<td>4</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr class="table-danger">
|
||||
<td>5</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr class="table-warning">
|
||||
<td>6</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
<tr class="table-active">
|
||||
<td>7</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
<td>Column content</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Cards
|
||||
|
||||
```vue
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="bs-component">
|
||||
<div class="card text-white bg-primary mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Primary card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-white bg-secondary mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Secondary card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-white bg-success mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Success card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-white bg-danger mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Danger card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-white bg-warning mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Warning card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-white bg-info mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Info card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-light mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Light card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card text-white bg-dark mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Dark card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="bs-component">
|
||||
<div class="card border-primary mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Primary card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-secondary mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Secondary card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-success mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Success card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-danger mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Danger card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-warning mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Warning card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-info mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Info card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-light mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Light card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card border-dark mb-3" style="max-width: 20rem;">
|
||||
<div class="card-header">Header</div>
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Dark card title</h4>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<div class="bs-component">
|
||||
<div class="card mb-3">
|
||||
<h3 class="card-header">Card header</h3>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Special title treatment</h5>
|
||||
<h6 class="card-subtitle text-muted">Support card subtitle</h6>
|
||||
</div>
|
||||
<img style="height: 200px; width: 100%; display: block;" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22318%22%20height%3D%22180%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20318%20180%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_158bd1d28ef%20text%20%7B%20fill%3Argba(255%2C255%2C255%2C.75)%3Bfont-weight%3Anormal%3Bfont-family%3AHelvetica%2C%20monospace%3Bfont-size%3A16pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_158bd1d28ef%22%3E%3Crect%20width%3D%22318%22%20height%3D%22180%22%20fill%3D%22%23777%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%22129.359375%22%20y%3D%2297.35%22%3EImage%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" alt="Card image">
|
||||
<div class="card-body">
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item">Cras justo odio</li>
|
||||
<li class="list-group-item">Dapibus ac facilisis in</li>
|
||||
<li class="list-group-item">Vestibulum at eros</li>
|
||||
</ul>
|
||||
<div class="card-body">
|
||||
<a href="javascript:void(0)" class="card-link">Card link</a>
|
||||
<a href="javascript:void(0)" class="card-link">Another link</a>
|
||||
</div>
|
||||
<div class="card-footer text-muted">
|
||||
2 days ago
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Card title</h4>
|
||||
<h6 class="card-subtitle mb-2 text-muted">Card subtitle</h6>
|
||||
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
|
||||
<a href="javascript:void(0)" class="card-link">Card link</a>
|
||||
<a href="javascript:void(0)" class="card-link">Another link</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -1,49 +0,0 @@
|
||||
## Buttons
|
||||
|
||||
```vue
|
||||
<button>Just a default button</button>
|
||||
```
|
||||
|
||||
```vue
|
||||
<a href="javascript:void(0)" class="action-button">An anchor with .action-button</a>
|
||||
```
|
||||
|
||||
All the crazy permutations of menu button...
|
||||
|
||||
```vue
|
||||
<a href="javascript:void(0)" class="menubutton">An anchor with .menu-button</a>
|
||||
```
|
||||
|
||||
```vue
|
||||
<a href="javascript:void(0)" class="menubutton popup">An anchor with .menu-button.popup</a>
|
||||
```
|
||||
|
||||
```vue
|
||||
<a href="javascript:void(0)" class="menubutton popup split">
|
||||
<a class="menubutton-label">An anchor with .menu-button.popup.split</a>
|
||||
</a>
|
||||
```
|
||||
|
||||
## Radio Buttons
|
||||
|
||||
As generated by mvc.ui.ui-options
|
||||
|
||||
```vue
|
||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="options" id="option1" autocomplete="off" checked> Active
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="options" id="option2" autocomplete="off"> Radio
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="options" id="option3" autocomplete="off"> Radio
|
||||
</label>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Pagination
|
||||
|
||||
```vue
|
||||
<ul class="pagination"><li class="page-item disabled"><a class="page-link" href="#page/1"><span class="fa fa-angle-double-left"></span></a></li><li class="page-item disabled"><a class="page-link" href="#page/1">0</a></li><li class="page-item active"><a class="page-link" href="#page/1">1</a></li><li class="page-item"><a class="page-link" href="#page/2">2</a></li><li class="page-item"><a class="page-link" href="#page/4"><span class="fa fa-angle-double-right"></span></a></li></ul>
|
||||
```
|
||||
@@ -1,55 +0,0 @@
|
||||
## Forms
|
||||
|
||||
Manually crafted "tool" form class, this is broken in the BS4 branch I think.
|
||||
|
||||
```vue
|
||||
<div class="tool-form">
|
||||
<form name="foo">
|
||||
<div class="form-row">
|
||||
<label>Label Input 1</label>
|
||||
<input id="input1" type="text" name="input1" size="40" />
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" id="send" name="submit" value="submit" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
```
|
||||
|
||||
Portlet variant generated by mvc.form.form-view
|
||||
|
||||
```vue
|
||||
<div class="ui-portlet-limited" id="uid-8">
|
||||
<div class="portlet-header">
|
||||
<div class="portlet-operations"></div>
|
||||
<div class="portlet-title">
|
||||
<i class="portlet-title-icon fa fa-unlock-alt" style="display: inline;"></i>
|
||||
<span class="portlet-title-text">Portlet Title</span></div>
|
||||
</div>
|
||||
<div class="portlet-content">
|
||||
<div class="portlet-body">
|
||||
<div class="ui-message alert alert-info"></div>
|
||||
<div>
|
||||
<div class="ui-form-element section-row">
|
||||
<div class="ui-form-error ui-error"><span class="fa fa-arrow-down"></span><span class="ui-form-error-text"></span></div>
|
||||
<div class="ui-form-title">
|
||||
<div class="ui-form-collapsible" style="display: none;">
|
||||
<i class="ui-form-collapsible-icon"></i>
|
||||
<span class="ui-form-collapsible-text"></span>
|
||||
</div>
|
||||
<span class="ui-form-title-text">Text Field 1</span>
|
||||
</div>
|
||||
<div class="ui-form-field">
|
||||
<input class="ui-input" id="field-uid-4" type="text">
|
||||
<span class="ui-form-info"></span>
|
||||
<div class="ui-form-backdrop" style="display: none;"></div>
|
||||
</div>
|
||||
<div class="ui-form-preview" style="display: none;"></div>
|
||||
</div>
|
||||
<div class="ui-form-element section-row">
|
||||
<div class="ui-form-error ui-error" style="display: none;"><span class="fa fa-arrow-down"></span><span class="ui-form-error-text"></span></div>
|
||||
<div class="ui-form-title"><div class="ui-form-collapsible" style="display: none;"><i class="ui-form-collapsible-icon"></i><span class="ui-form-collapsible-text"></span></div><span class="ui-form-title-text" style="display: inline;">Password</span></div>
|
||||
<div class="ui-form-field">
|
||||
<input class="ui-input" type="password"><span class="ui-form-info"></span><div class="ui-form-backdrop" style="display: none;"></div></div><div class="ui-form-preview" style="display: none;"></div></div>
|
||||
<div class="ui-form-element section-row" id="uid-7" style="display: none;"><div class="ui-form-error ui-error" style="display: none;"><span class="fa fa-arrow-down"></span><span class="ui-form-error-text"></span></div><div class="ui-form-title"><div class="ui-form-collapsible" style="display: none;"><i class="ui-form-collapsible-icon"></i><span class="ui-form-collapsible-text"></span></div><span class="ui-form-title-text" style="display: inline;">token</span></div><div class="ui-form-field"><div id="field-uid-7"><div style="display: none;"></div><div></div></div><span class="ui-form-info"></span><div class="ui-form-backdrop" style="display: none;"></div></div><div class="ui-form-preview" style="display: none;"></div></div></div></div><div class="portlet-buttons"><button type="button" class="ui-button-default btn btn-primary ui-clear-float" id="submit" data-original-title="" title=""><i class="icon fa fa-save ui-margin-right"></i><span class="title">Submit</span><div class="progress" style="display: none;"><div class="progress-bar" style="width: 0%;"></div></div></button></div></div><div class="portlet-backdrop"></div></div>
|
||||
```
|
||||
@@ -1,69 +0,0 @@
|
||||
## Masthead
|
||||
|
||||
As generated by layout.masthead.js
|
||||
|
||||
Default height:
|
||||
|
||||
```vue
|
||||
<nav id="masthead" class="navbar navbar-expand justify-content-center navbar-dark bg-dark">
|
||||
<a class="navbar-brand">
|
||||
<img class="navbar-brand-image"/>
|
||||
<span class="navbar-brand-title">Title</span>
|
||||
</a>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link">Header 1</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle">Header 2</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link">Active Header</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
```
|
||||
|
||||
Override height with "height: 80px;"
|
||||
|
||||
```vue
|
||||
<nav id="masthead" class="navbar navbar-expand justify-content-center navbar-dark bg-dark" style="height: 80px;">
|
||||
<a class="navbar-brand">
|
||||
<img class="navbar-brand-image"/>
|
||||
<span class="navbar-brand-title">Title</span>
|
||||
</a>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link">Header 1</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle">Header 2</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link">Active Header</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
```
|
||||
|
||||
Override height with "height: 4rem;"
|
||||
|
||||
```vue
|
||||
<nav id="masthead" class="navbar navbar-expand justify-content-center navbar-dark bg-dark" style="height: 4rem;">
|
||||
<a class="navbar-brand">
|
||||
<img class="navbar-brand-image"/>
|
||||
<span class="navbar-brand-title">Title</span>
|
||||
</a>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link">Header 1</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle">Header 2</a>
|
||||
</li>
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link">Active Header</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
```
|
||||
@@ -1,19 +0,0 @@
|
||||
## Popup menus
|
||||
|
||||
These are the classes for the menu itself, normally floating, so placed inside
|
||||
a relative element.
|
||||
|
||||
```vue
|
||||
<div style="position: relative; height: 12rem;">
|
||||
<div class="popmenu-wrapper" style="top: 0;">
|
||||
<ul class="dropdown-menu">
|
||||
<li class="head"><a>Heading one</a></li>
|
||||
<li><a>An item</a></li>
|
||||
<li><a>Another item</a></li>
|
||||
<li class="head"><a>Heading two</a></li>
|
||||
<li><a>Third item</a></li>
|
||||
<li><a>Last item</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -1,33 +0,0 @@
|
||||
### Panel Messages
|
||||
|
||||
Messages that appear across the top of the panel view below the masthead.
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<div v-for="type in ['done', 'info', 'warning', 'error']">
|
||||
<div v-bind:class="'panel-' + type + '-message'">I'm a panel-{{type}}-message</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Large Messages
|
||||
|
||||
Used for providing feedback inline.
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<div v-for="type in ['done', 'info', 'warning', 'error']">
|
||||
<div v-bind:class="type + 'messagelarge'">I'm a {{type}}messagelarge</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Small Messages
|
||||
|
||||
```vue
|
||||
<div>
|
||||
<div v-for="type in ['done', 'info', 'warning', 'error']">
|
||||
<div v-bind:class="type + 'message'">I'm a {{type}}message</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -1,20 +0,0 @@
|
||||
## Panel (toolMenuContainer)
|
||||
|
||||
```vue
|
||||
<div style="height: 200px;">
|
||||
<div style="position: absolute; width: 250px; height: 200px; border: dotted gray 1px">
|
||||
<div class="unified-panel-header">
|
||||
<div class="unified-panel-header-inner">
|
||||
Header
|
||||
</div>
|
||||
</div>
|
||||
<div class="unified-panel-body">
|
||||
<div class="toolMenuContainer">
|
||||
one<br>
|
||||
two<br>
|
||||
three<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
@@ -1,14 +0,0 @@
|
||||
## Tables
|
||||
|
||||
Tables using the .grid class
|
||||
|
||||
```vue
|
||||
<table class="grid">
|
||||
<thead class="grid-table-header">
|
||||
<tr><th>One</th><th>Two</th></tr>
|
||||
</thead>
|
||||
<tbody class="grid-table-body">
|
||||
<tr><td>Value 1</td><td>Value 2</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
```
|
||||
@@ -1,32 +0,0 @@
|
||||
## Tabs
|
||||
|
||||
Tabs as generated by mvc.ui.ui-tabs
|
||||
|
||||
```vue
|
||||
<ul style="display: flex;" class="tab-navigation nav nav-tabs">
|
||||
<li class="tab-element nav-item" id="tab-attribute" style="display: list-item;" data-original-title="" title="">
|
||||
<a class="nav-link active" id="tab-title-link-attribute">
|
||||
<i class="tab-icon fa fa-bars"></i>
|
||||
<span id="tab-title-text-attribute" class="tab-title-text">Attributes</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab-element nav-item" id="tab-convert" style="display: list-item;" data-original-title="" title="">
|
||||
<a class="nav-link" id="tab-title-link-convert">
|
||||
<i class="tab-icon fa fa-gear"></i>
|
||||
<span id="tab-title-text-convert" class="tab-title-text">Convert</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab-element nav-item" id="tab-datatype" style="display: list-item;" data-original-title="" title="">
|
||||
<a class="nav-link" id="tab-title-link-datatype">
|
||||
<i class="tab-icon fa fa-database"></i>
|
||||
<span id="tab-title-text-datatype" class="tab-title-text">Datatypes</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab-element nav-item" id="tab-permissions" style="display: list-item;" data-original-title="" title="">
|
||||
<a class="nav-link" id="tab-title-link-permissions">
|
||||
<i class="tab-icon fa fa-user"></i>
|
||||
<span id="tab-title-text-permissions" class="tab-title-text">Permissions</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./scripts/"
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-card class="citation-card" v-if="!simple" header-tag="nav">
|
||||
<template v-slot:header>
|
||||
<b-nav card-header tabs>
|
||||
<b-nav-item
|
||||
:active="outputFormat === outputFormats.CITATION"
|
||||
@click="outputFormat = outputFormats.CITATION"
|
||||
>Citations (APA)</b-nav-item
|
||||
>
|
||||
<b-nav-item
|
||||
:active="outputFormat === outputFormats.BIBTEX"
|
||||
@click="outputFormat = outputFormats.BIBTEX"
|
||||
>BibTeX</b-nav-item
|
||||
>
|
||||
</b-nav>
|
||||
</template>
|
||||
<div v-if="source === 'histories'" class="infomessage">
|
||||
When writing up your analysis, remember to include all references that should be cited in order to
|
||||
completely describe your work. Also, please remember to
|
||||
<a href="https://galaxyproject.org/citing-galaxy">cite Galaxy</a>.
|
||||
</div>
|
||||
<div class="citations-formatted">
|
||||
<template v-for="citation in formattedCitations">
|
||||
<div :key="citation" class="formatted-reference" v-html="citation"></div>
|
||||
</template>
|
||||
</div>
|
||||
</b-card>
|
||||
<div v-else-if="formattedCitations.length">
|
||||
<b-btn v-b-toggle="id" variant="primary">Citations</b-btn>
|
||||
<b-collapse
|
||||
:id="id.replace(/ /g, '_')"
|
||||
class="mt-2"
|
||||
@show="$emit('show')"
|
||||
@shown="$emit('shown')"
|
||||
@hide="$emit('hide')"
|
||||
@hidden="$emit('hidden')"
|
||||
>
|
||||
<b-card>
|
||||
<template v-for="citation in formattedCitations">
|
||||
<div :key="citation" class="formatted-reference" v-html="citation"></div>
|
||||
</template>
|
||||
</b-card>
|
||||
</b-collapse>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Vue from "vue";
|
||||
import BootstrapVue from "bootstrap-vue";
|
||||
import axios from "axios";
|
||||
import Cite from "citation-js";
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
|
||||
Vue.use(BootstrapVue);
|
||||
|
||||
const outputFormats = Object.freeze({
|
||||
CITATION: "bibliography",
|
||||
BIBTEX: "bibtex",
|
||||
RAW: "raw",
|
||||
});
|
||||
|
||||
export default {
|
||||
props: {
|
||||
source: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
simple: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
citations: [],
|
||||
errors: [],
|
||||
showCollapse: false,
|
||||
outputFormats,
|
||||
outputFormat: outputFormats.CITATION,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
formattedCitations() {
|
||||
const processed = [];
|
||||
if (this.citations.length !== 0) {
|
||||
for (const c of this.citations) {
|
||||
let link = "";
|
||||
if (c.cite.data && c.cite.data[0] && c.cite.data[0].URL) {
|
||||
link = ` <a href="${c.cite.data[0].URL}" target="_blank">[Link]</a>`;
|
||||
}
|
||||
const formattedCitation = c.cite.format(this.outputFormat, {
|
||||
format: "html",
|
||||
template: "apa",
|
||||
lang: "en-US",
|
||||
append: link,
|
||||
});
|
||||
processed.push(formattedCitation);
|
||||
}
|
||||
}
|
||||
return processed;
|
||||
},
|
||||
},
|
||||
updated() {
|
||||
this.$nextTick(() => {
|
||||
this.$emit("rendered");
|
||||
});
|
||||
},
|
||||
created() {
|
||||
axios
|
||||
.get(`${getAppRoot()}api/${this.source}/${this.id}/citations`)
|
||||
.then((response) => {
|
||||
response.data.forEach((rawCitation) => {
|
||||
try {
|
||||
const cite = new Cite(rawCitation.content);
|
||||
this.citations.push({ raw: rawCitation.content, cite: cite });
|
||||
} catch (err) {
|
||||
console.warn(`Error parsing bibtex: ${err}`);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.citation-card .card-header .nav-tabs {
|
||||
margin-bottom: -0.75rem !important;
|
||||
}
|
||||
.formatted-reference {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user