Skip to content

Commit 1c69e89

Browse files
committed
Merge branch 'develop' into gha_ci_reduce
2 parents 3da393a + bbf0c71 commit 1c69e89

34 files changed

+895
-147
lines changed

.github/workflows/end2end.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: End-to-end test of EasyBuild in different distros
2+
on: [push, pull_request]
3+
jobs:
4+
build_publish:
5+
name: End-to-end test
6+
runs-on: ubuntu-latest
7+
strategy:
8+
matrix:
9+
container:
10+
- centos-7.9
11+
- centos-8.5
12+
- fedora-36
13+
- opensuse-15.4
14+
- rockylinux-8.8
15+
- rockylinux-9.2
16+
- ubuntu-20.04
17+
- ubuntu-22.04
18+
fail-fast: false
19+
container:
20+
image: ghcr.io/easybuilders/${{ matrix.container }}-amd64
21+
steps:
22+
- name: Check out the repo
23+
uses: actions/checkout@v3
24+
25+
- name: download and unpack easyblocks and easyconfigs repositories
26+
run: |
27+
cd $HOME
28+
for pkg in easyblocks easyconfigs; do
29+
curl -OL https://github.com/easybuilders/easybuild-${pkg}/archive/develop.tar.gz
30+
tar xfz develop.tar.gz
31+
rm -f develop.tar.gz
32+
done
33+
34+
- name: Set up environment
35+
shell: bash
36+
run: |
37+
# collect environment variables to be set in subsequent steps in script that can be sourced
38+
echo "export PATH=$PWD:$PATH" > /tmp/eb_env
39+
echo "export PYTHONPATH=$PWD:$HOME/easybuild-easyblocks-develop:$HOME/easybuild-easyconfigs-develop" >> /tmp/eb_env
40+
41+
- name: Run commands to check test environment
42+
shell: bash
43+
run: |
44+
cmds=(
45+
"whoami"
46+
"pwd"
47+
"env | sort"
48+
"eb --version"
49+
"eb --show-system-info"
50+
"eb --check-eb-deps"
51+
"eb --show-config"
52+
)
53+
for cmd in "${cmds[@]}"; do
54+
echo ">>> $cmd"
55+
sudo -u easybuild bash -l -c "source /tmp/eb_env; $cmd"
56+
done
57+
58+
- name: End-to-end test of installing bzip2 with EasyBuild
59+
shell: bash
60+
run: |
61+
sudo -u easybuild bash -l -c "source /tmp/eb_env; eb bzip2-1.0.8.eb --trace --robot"
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# documentation: https://help.github.com/en/articles/workflow-syntax-for-github-actions
2+
name: EasyBuild framework unit tests (python2)
3+
on: [push, pull_request]
4+
5+
permissions:
6+
contents: read # to fetch code (actions/checkout)
7+
8+
concurrency:
9+
group: ${{format('{0}:{1}:{2}', github.repository, github.ref, github.workflow)}}
10+
cancel-in-progress: true
11+
12+
jobs:
13+
test_python2:
14+
runs-on: ubuntu-20.04
15+
container:
16+
# CentOS 7.9 container that already includes Lmod & co,
17+
# see https://github.com/easybuilders/easybuild-containers
18+
image: ghcr.io/easybuilders/centos-7.9-amd64
19+
steps:
20+
- uses: actions/checkout@v3
21+
22+
- name: install Python packages
23+
run: |
24+
# Python packages
25+
python2 -V
26+
python2 -m pip --version
27+
python2 -m pip install --upgrade pip
28+
python2 -m pip --version
29+
# strip out GC3Pie since installation with ancient setuptools (0.9.8) fails
30+
sed -i '/GC3Pie/d' requirements.txt
31+
python2 -m pip install -r requirements.txt
32+
# git config is required to make actual git commits (cfr. tests for GitRepository)
33+
sudo -u easybuild git config --global user.name "GitHub Actions"
34+
sudo -u easybuild git config --global user.email "[email protected]"
35+
sudo -u easybuild git config --get-regexp 'user.*'
36+
37+
- name: install GitHub token (if available)
38+
env:
39+
# token (owned by @boegelbot) with gist permissions (required for some of the tests for GitHub integration);
40+
# this token is not available in pull requests, so tests that require it are skipped in PRs,
41+
# and are only run after the PR gets merged
42+
GITHUB_TOKEN: ${{secrets.CI_UNIT_TESTS_GITHUB_TOKEN}}
43+
run: |
44+
# tests that require a GitHub token are skipped automatically when no GitHub token is available
45+
if [ ! -z $GITHUB_TOKEN ]; then
46+
sudo -u easybuild python2 -c "import keyring; import keyrings.alt.file; keyring.set_keyring(keyrings.alt.file.PlaintextKeyring()); keyring.set_password('github_token', 'easybuild_test', '$GITHUB_TOKEN')";
47+
echo "GitHub token installed!"
48+
else
49+
echo "Installation of GitHub token skipped!"
50+
fi
51+
52+
- name: install sources
53+
run: |
54+
# install from source distribution tarball, to test release as published on PyPI
55+
python2 setup.py sdist
56+
ls dist
57+
export PREFIX=/tmp/$USER/$GITHUB_SHA
58+
python2 -m pip install --prefix $PREFIX dist/easybuild-framework*tar.gz
59+
60+
- name: run test suite
61+
run: |
62+
# run tests *outside* of checked out easybuild-framework directory,
63+
# to ensure we're testing installed version (see previous step)
64+
cd $HOME
65+
# make sure 'eb' is available via $PATH, and that $PYTHONPATH is set (some tests expect that)
66+
export PREFIX=/tmp/$USER/$GITHUB_SHA
67+
ENV_CMDS="export PATH=$PREFIX/bin:$PATH; export PYTHONPATH=$PREFIX/lib/python2.7/site-packages:$PYTHONPATH"
68+
ENV_CMDS="${ENV_CMDS}; export EB_VERBOSE=1; export EB_PYTHON=python2; export TEST_EASYBUILD_SILENCE_DEPRECATION_WARNINGS=python2"
69+
# run EasyBuild command via (non-root) easybuild user + login shell
70+
sudo -u easybuild bash -l -c "${ENV_CMDS}; module --version; eb --version"
71+
# show active EasyBuild configuration
72+
sudo -u easybuild bash -l -c "${ENV_CMDS}; eb --show-config"
73+
# gather some useful info on test system
74+
sudo -u easybuild bash -l -c "${ENV_CMDS}; eb --show-system-info"
75+
# check GitHub configuration
76+
sudo -u easybuild bash -l -c "${ENV_CMDS}; eb --check-github --github-user=easybuild_test"
77+
# create file owned by root but writable by anyone (used by test_copy_file)
78+
sudo touch /tmp/file_to_overwrite_for_easybuild_test_copy_file.txt
79+
sudo chmod o+w /tmp/file_to_overwrite_for_easybuild_test_copy_file.txt
80+
# run test suite (via easybuild user + login shell)
81+
sudo -u easybuild bash -l -c "${ENV_CMDS}; python2 -O -m test.framework.suite"

RELEASE_NOTES

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,34 @@ For more detailed information, please see the git log.
44
These release notes can also be consulted at https://easybuild.readthedocs.io/en/latest/Release_notes.html.
55

66

7+
v4.8.1 (11 September 2023)
8+
--------------------------
9+
10+
update/bugfix release
11+
12+
- various enhancements, including:
13+
- add end-to-end test for running EasyBuild in different Linux distros using containers (#3968)
14+
- suggest default title in `--review-pr` (#4287)
15+
- add `build_and_install_loop` hooks to run before and after the install loop for individual easyconfigs (#4304)
16+
- implement support for `cancel_hook` and `fail_hook` (#4315, #4325)
17+
- add postiter hook to the list of steps so the corresponding hook can be used (#4316)
18+
- add `run_shell_cmd` hook (#4323)
19+
- add `build_info_msg` easyconfig parameter to print message during installation of an easyconfig (#4324)
20+
- add `--silence-hook-trigger` configuration option to supress printing of debug message every time a hook is triggered (#4329)
21+
- add support for using fine grained Github tokens (#4332)
22+
- add definitions for ifbf and iofbf toolchain (#4337)
23+
- add support for submodule filtering and specifying extra Git configuration in `git_config` (#4338, #4339)
24+
- various bug fixes, including:
25+
- improve error when checksum dict has no entry for a file (#4150)
26+
- avoid error being logged when `checksums.json` is not found (#4261)
27+
- don't fail in `mkdir` if path gets created while processing it (#4300, #4328)
28+
- ignore request for external module (meta)data when no modules tool is active (#4308)
29+
- use sys.executable to obtain path to `python` command in tests, rather than assuming that `python` command is available in `$PATH` (#4309)
30+
- fix `test_add_and_remove_module_path` by replacing string comparison of paths by checking whether they point to the same path (since symlinks may cause trouble) (#4312)
31+
- enhance `Toolchain.get_flag` to handle lists (#4319)
32+
- only add extensions in module file if there are extensions (#4331)
33+
34+
735
v4.8.0 (7 July 2023)
836
--------------------
937

easybuild/framework/easyblock.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,13 @@ def get_checksums_from_json(self, always_read=False):
395395
:param always_read: always read the checksums.json file, even if it has been read before
396396
"""
397397
if always_read or self.json_checksums is None:
398-
try:
399-
path = self.obtain_file("checksums.json", no_download=True)
398+
path = self.obtain_file("checksums.json", no_download=True, warning_only=True)
399+
if path is not None:
400400
self.log.info("Loading checksums from file %s", path)
401401
json_txt = read_file(path)
402402
self.json_checksums = json.loads(json_txt)
403-
# if the file can't be found, return an empty dict
404-
except EasyBuildError:
403+
else:
404+
# if the file can't be found, return an empty dict
405405
self.json_checksums = {}
406406

407407
return self.json_checksums
@@ -736,7 +736,8 @@ def collect_exts_file_info(self, fetch_files=True, verify_checksums=True):
736736
return exts_sources
737737

738738
def obtain_file(self, filename, extension=False, urls=None, download_filename=None, force_download=False,
739-
git_config=None, no_download=False, download_instructions=None, alt_location=None):
739+
git_config=None, no_download=False, download_instructions=None, alt_location=None,
740+
warning_only=False):
740741
"""
741742
Locate the file with the given name
742743
- searches in different subdirectories of source path
@@ -789,7 +790,13 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
789790
return fullpath
790791

791792
except IOError as err:
792-
raise EasyBuildError("Downloading file %s from url %s to %s failed: %s", filename, url, fullpath, err)
793+
if not warning_only:
794+
raise EasyBuildError("Downloading file %s "
795+
"from url %s to %s failed: %s", filename, url, fullpath, err)
796+
else:
797+
self.log.warning("Downloading file %s "
798+
"from url %s to %s failed: %s", filename, url, fullpath, err)
799+
return None
793800

794801
else:
795802
# try and find file in various locations
@@ -866,8 +873,13 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
866873
self.dry_run_msg(" * %s (MISSING)", filename)
867874
return filename
868875
else:
869-
raise EasyBuildError("Couldn't find file %s anywhere, and downloading it is disabled... "
876+
if not warning_only:
877+
raise EasyBuildError("Couldn't find file %s anywhere, and downloading it is disabled... "
878+
"Paths attempted (in order): %s ", filename, ', '.join(failedpaths))
879+
else:
880+
self.log.warning("Couldn't find file %s anywhere, and downloading it is disabled... "
870881
"Paths attempted (in order): %s ", filename, ', '.join(failedpaths))
882+
return None
871883
elif git_config:
872884
return get_source_tarball_from_git(filename, targetdir, git_config)
873885
else:
@@ -959,7 +971,11 @@ def obtain_file(self, filename, extension=False, urls=None, download_filename=No
959971
error_msg += "and downloading it didn't work either... "
960972
error_msg += "Paths attempted (in order): %s " % failedpaths_msg
961973

962-
raise EasyBuildError(error_msg, filename)
974+
if not warning_only:
975+
raise EasyBuildError(error_msg, filename)
976+
else:
977+
self.log.warning(error_msg, filename)
978+
return None
963979

964980
#
965981
# GETTER/SETTER UTILITY FUNCTIONS
@@ -4174,6 +4190,10 @@ def build_and_install_one(ecdict, init_env):
41744190
dry_run_msg('', silent=silent)
41754191
print_msg("processing EasyBuild easyconfig %s" % spec, log=_log, silent=silent)
41764192

4193+
if ecdict['ec']['build_info_msg']:
4194+
msg = "This easyconfig provides the following build information:\n\n%s\n"
4195+
print_msg(msg % ecdict['ec']['build_info_msg'], log=_log, silent=silent)
4196+
41774197
if dry_run:
41784198
# print note on interpreting dry run output (argument is reference to location of dry run messages)
41794199
print_dry_run_note('below', silent=silent)

easybuild/framework/easyconfig/default.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,8 @@
228228
'buildstats': [None, "A list of dicts with build statistics", OTHER],
229229
'deprecated': [False, "String specifying reason why this easyconfig file is deprecated "
230230
"and will be archived in the next major release of EasyBuild", OTHER],
231+
'build_info_msg': [None, "String with information to be printed to stdout and logged during the building "
232+
"of the easyconfig", OTHER],
231233
}
232234

233235

easybuild/framework/easyconfig/easyconfig.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
from easybuild.tools.module_naming_scheme.mns import DEVEL_MODULE_SUFFIX
7474
from easybuild.tools.module_naming_scheme.utilities import avail_module_naming_schemes, det_full_ec_version
7575
from easybuild.tools.module_naming_scheme.utilities import det_hidden_modname, is_valid_module_name
76-
from easybuild.tools.modules import modules_tool
76+
from easybuild.tools.modules import modules_tool, NoModulesTool
7777
from easybuild.tools.py2vs3 import OrderedDict, create_base_metaclass, string_type
7878
from easybuild.tools.systemtools import check_os_dependency, pick_dep_version
7979
from easybuild.tools.toolchain.toolchain import SYSTEM_TOOLCHAIN_NAME, is_system_toolchain
@@ -1306,6 +1306,9 @@ def probe_external_module_metadata(self, mod_name, existing_metadata=None):
13061306
:param existing_metadata: already available metadata for this external module (if any)
13071307
"""
13081308
res = {}
1309+
if isinstance(self.modules_tool, NoModulesTool):
1310+
self.log.debug('Ignoring request for external module data for %s as no modules tool is active', mod_name)
1311+
return res
13091312

13101313
if existing_metadata is None:
13111314
existing_metadata = {}

easybuild/framework/easyconfig/tools.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
from easybuild.tools.filetools import find_easyconfigs, is_patch_file, locate_files
6161
from easybuild.tools.filetools import read_file, resolve_path, which, write_file
6262
from easybuild.tools.github import GITHUB_EASYCONFIGS_REPO
63-
from easybuild.tools.github import det_pr_labels, download_repo, fetch_easyconfigs_from_pr, fetch_pr_data
63+
from easybuild.tools.github import det_pr_labels, det_pr_title, download_repo, fetch_easyconfigs_from_pr, fetch_pr_data
6464
from easybuild.tools.github import fetch_files_from_pr
6565
from easybuild.tools.multidiff import multidiff
6666
from easybuild.tools.py2vs3 import OrderedDict
@@ -561,6 +561,11 @@ def review_pr(paths=None, pr=None, colored=True, branch='develop', testing=False
561561
lines.extend(['', "This PR is associated with a generic '.x' milestone, "
562562
"it should be associated to the next release milestone once merged"])
563563

564+
default_new_title = det_pr_title([ec['ec'] for ec in ecs])
565+
if default_new_title != pr_data['title']:
566+
lines.extend(['', "If this PR contains only new easyconfigs and has not been edited from the default, "
567+
"then the title should be: %s" % default_new_title])
568+
564569
return '\n'.join(lines)
565570

566571

0 commit comments

Comments
 (0)