-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jenkins: make it possible to run notebooks from external repos programmatically #138
base: master
Are you sure you want to change the base?
Conversation
However, old "download all default repos" have to be preserved for back-compat with other external scripts. Fixes #30
…METERS_SCRIPT_URL
…b from new repos No need to update 'archiveArtifacts' in Jenkinsfile anymore. Since we only download enabled repos, we could not hardcode artifact repo list anyways. DEFAULT_PRODUCTION_HOST also overridable for other repos.
…g files created by the script
…from being logged
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The optional download is a nice feature. See comment about its default.
Love the reuse of functions for recurring operations.
Not really sure about some other design choices.
Waiting on tests to complete to see if any other items are problematic.
if [ -z "$DOWNLOAD_ALL_DEFAULT_REPOS" ]; then | ||
# Back-compat with old default behavior, used in binder/reorg-notebook | ||
# and other external scripts that autodeploy tutorial notebooks (see | ||
# https://github.com/bird-house/birdhouse-deploy/blob/444a7c35a31aa8ad351e47f659383ba5c2919705/birdhouse/deployment/trigger-deploy-notebook#L64-L75) | ||
DOWNLOAD_ALL_DEFAULT_REPOS=true | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would rather have the other script set DOWNLOAD_ALL_DEFAULT_REPOS=true
if it needs all of them and have the default behavior of skipping unnecessary downloads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, that's the point. If the other scripts have to set this new DOWNLOAD_ALL_DEFAULT_REPOS=true
it means I break backward-compatibility with the other scripts.
I want no changes to other scripts outside this repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead, every CI needs to inject the new variable to take advantage of more intelligent download rather than getting it for free. Since birdhouse-deploy does wget
to retrieve those scripts, it makes more sense IMO that it updates with new features, or use an explicit commit hash or tag to ensure the behavior remains consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
every CI needs to inject the new variable to take advantage of more intelligent download
Huh, the only one is this Jenkins or more precisely the testall
script. If someone deploy this job on another server, the entrypoint is still the testall
script, not this downloadrepos
directly.
use an explicit commit hash or tag to ensure the behavior remains consistent.
Using exact commit hash is like pinning everything in your requirements.txt
. We do not do this because update will be too tedious, same here.
downloadrepos
Outdated
# Presence of setup.cfg, tox.ini, pyproject.toml files confuse py.test execution rootdir discovery. | ||
# USAGE: delete_files_confusing_pytest "$CHECKOUT_DIR" | ||
delete_files_confusing_pytest() { | ||
for afile in setup.cfg tox.ini pyproject.toml; do | ||
if [ -f "$1/$afile" ]; then | ||
rm -v "$1/$afile" | ||
fi | ||
done | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the repository defined pytest options, such as necessary plugins or marker definitions, this will break their execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this is weird. I have no other hypothesis other can because I run multiple notebooks from multiple repos at the same time, if each repo has their config, it breaks the full test run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case we should be running a separate py.test
process for each repo instead of all at once.
I agree with @fmigneault that there could be crucial definitions in the setup.cfg tox.ini pyproject.toml
files that we do not want to lose or the tests may fail unexpectedly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible those pytest definitions are for the unit test but here we are running notebook tests so they do not apply? Because for the current list of repos hardcoded in this Jenkins config, missing those pytest definitions are absolutely fine since forever. Keeping them are actually causing trouble.
The step to remove those files setup.cfg tox.ini pyproject.toml
are not hardcoded so for external repos, they can choose to keep them if needed. See example in jenkins-params-external-repos.include.sh
delete_files_confusing_pytest "$ROOK_DIR" |
delete_files_confusing_pytest
.
Jenkinsfile
Outdated
archiveArtifacts(artifacts: 'esgf-compute-api-*/examples/*.ipynb', fingerprint: true) | ||
archiveArtifacts(artifacts: 'PAVICS-landing-*/content/notebooks/climate_indicators/*.ipynb', fingerprint: true) | ||
archiveArtifacts(artifacts: 'buildout/*.output.ipynb', fingerprint: true, allowEmptyArchive: true) | ||
archiveArtifacts(artifacts: 'buildout/*.ipynb', fingerprint: true, allowEmptyArchive: true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use a buildout/**/*.ipynb
and leave the directory structure as originally defined by each repository? That would avoid all the directory renaming manipulations and potential side effects of removing pytest configs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I previously thought that too. But actually real life usage, a flat directory is much easier to use, meaning to download the notebooks I want. In a nested layout, if I want multiple notebooks under multiple different sub-folders, I have to click a lot more. It's tiring.
Now with the option to only archive the notebooks enabled for the run, the chance to have name clash is even lower.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would avoid all the directory renaming manipulations and potential side effects of removing pytest configs.
Not sure what you mean. I do not perform any directory renaming manipulations. The notebooks are run from the original location of the checkout because some will use relative path to get their test data in the same checkout.
I only copy the notebooks only, not the test data, to the buildout/
folder so they are archived by Jenkins, along side their matching "output" notebook so we can download both of them and diff them manually if the diff presented by Jenkins console output is impossible to understand.
As for "potential side effects of removing pytest configs", I also do not understand how that relate to Jenkins archiving config change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the notebooks are copied as a flat list, which could lead to conflicts between repositories. I was under the impression that the repository name was used as prefix to the archived notebook names to avoid this, but it is not the case. With the results archived this way, it is very hard to trace back the original source of the notebook.
As for "potential side effects of removing pytest configs", I also do not understand how that relate to Jenkins archiving config change.
It does not affect the archiving, but it affects how the notebooks are executed by pytest
in order to generate their outputs. Therefore, if any pytest
configurations options are applied to obtain certain effects needed by the tests, this could have bad side effects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is very hard to trace back the original source of the notebook.
I never had trouble knowing which nb is from which repo but I agree not everyone know this. Just so it is clear, it is already like this before (flat list of *.output.ipynb
), I am just adding the original along-side the corresponding output.ipynb
.
However, I'll add the repo name as prefix to the nb filename to help differentiate and avoid name clash.
By the way, I did preserve the already existing name clash prevention:
PAVICS-e2e-workflow-tests/runtest
Lines 88 to 89 in d6fd500
# prevent name clash | |
filename="${filename}_`date '+%s'`" |
It does not affect the archiving
But you had your comment in this Jenkins archiving section so that's why I was mixed up.
Like I said here #138 (comment), it weird but I had to do it, otherwise the test run do not work at all. The only hypothesis I have is mentioned in that comment.
By the way, deleting the extra files is an existing behavior. I did not just add it.
This PR is maximally backward-compatible. I did not add any new processing steps other than making these processing steps available to external repos.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"look at the output in the artifact"? You mean look at the output in the "Console Output"?
No, I open the notebook directly from the artifacts page and look at its contents from the browser.
Because if you only look at the list of saved notebooks in the artifacts, you won't know which notebooks actually failed.
If I went through the artifact to look for a notebook, it's because I already know which test case I'm investigating to debug.
The listing of notebooks in the "Console Output" where any errors are also found, are using the original structure, not flat. This will give you exactly the repo and path of the notebook you want to run manually.
This is exactly why I would rather have the notebooks with the generated outputs located under the same locations as the current artifacts using the same structure as displayed in the console outputs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exactly why I would rather have the notebooks with the generated outputs located under the same locations as the current artifacts using the same structure as displayed in the console outputs.
@fmigneault
Okay, how about I make all the files (original and output) keep the same folder structure as prefix. Then you have your structure to easy search for your file, I have my flat list to easily switch between multiples repos.
Something like buildout/pavics-sdi-master--docs--source--notebooks--WCS_example{,-output]}.ipynb
. Good enough compromise so we can merge this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is a matter of compromise. The artifact structure should simply reflect the source repository. There is no need for an alternate naming convention and there is no need to define more code to handle it. The outputs should simply be saved where the notebooks are naturally collected in artifacts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it is a matter of compromise.
Agreed, no compromise for usability.
Let me repeat comment #138 (comment) again if not clear enough: if "notebooks are under different nested folders ! You'll have to click to get to the first older, back out, then again to the 2nd folder ! The more folders, the more back and forth it is !!!"
Just a reminder, this artifact archiving just for immediate troubleshooting, it has no long term persistance value. I'd rather focus on usability and productivity than following some standard for something that is ephemeral and not important. Once you manage a lot of notebook repos, a flat list if much faster to deal with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even then, I do not agree. If you know the path of the notebook you are interested in after getting an error, you have no reason to go back-and-forth between folders.
I see the addition of code, special character handling and deletion of repo-specific configs as a sign of bigger maintenance burden and potential side effects.
…po they came from and further avoid name clash
…dd-new-nb-or-repos
…dd-new-nb-or-repos
644e1ec
to
7fce738
Compare
@fmigneault Apologies for taking more than haft a year to come back to this PR after our discussion. I was completely under the water. So per our previous discussion, you wanted
@mishaschwartz Just FYI, with this PR, you will be able to run any notebooks unknown to this repo, as long as the docker images has the required packages to run the notebook. As a demo, the sample config file |
@tlvu |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait for answer regarding file path handling vs override function.
@fmigneault the current behavior for the output file is already a flat list ! This PR basically harmonize also the location of the original file to be next to the output file. Currently the output file is flat but the original file is nested. The output file is the most important one as it contains the error or the refreshed output to be used when refreshing notebooks output. |
I don't know which source you use that makes you think this, but our server definition doesn't override anything and presents the artifacts in a hierarchy: Given the PR introduces: choose_artifact_filename() {
echo "$1" | sed "s@/@__@g"
} This explicitly replaces the In other words, what I want as a result of this PR is that, without any need of an override, the notebooks found in eg. |
@fmigneault I think you guys override And the reason is to save time since a 2nd run means doubling the time of the CI pipeline and the pass or failure status of the pipeline only depend on the first run ( If you happen to not override that config, then all the output file are flat under Here is the screenshot of the currently flat output files from our end: |
Ok. As long as it doesn't affect the output structure of the notebooks. I still find it odd that a flat list would be used. Why not just dump the |
That's exactly the intend of this change: put the The screenshot I showed you was on |
I don't think you got what I meant by next to the
No replace of If you want to replace the
But in either case, you don't get a mixture of nested and non-nested directories. I went back to older comments when I did try using that branch, and got a flat list as shown in #138 (comment). |
This is done via the
CONFIG_PARAMETERS_SCRIPT_URL
override. See the samplejenkins-params-external-repos.include.sh
where I run external notebooks from https://github.com/roocs/rook/tree/master/notebooks.Changes:
setup.cfg
tox.ini
andpyproject.toml
files.archiveArtifacts
inJenkinsfile
because the list of repos is dynamic now.buildout/
dir, together with their corresponding*.output.ipynb
files. Previously they were at the same checkout path as their repo.CONFIG_OVERRIDE_SCRIPT_URL
, see demo intest-override/jenkins-params-external-repos.include.sh
downloadrepos
is both a script and a library to centralize all helper functions in one place. Otherwise we would have helpers for downloading repos in one file and helpers for other tasks in other files. Backward compatibility is preserved whendownloadrepos
is used as a script in autodeploy of tutorial notebooks to the Jupyter env.test-override/jenkins-params-external-repos.include.sh
NBVAL_SANITIZE_CFG_FILE
andDEFAULT_PRODUCTION_HOST
now can also be overridden by the external repo if needed.This PR is almost fixing #57.
There is no easy way to programmatically change the Jenkins "build request UI" to add on-the-fly the new params for the external repo. I think we will have to have another separate
Jenkinsfile.other_repo
.This PR would help testing bird-house/birdhouse-deploy#455.
@mishaschwartz This would be useful to you if you have notebooks for your own WPS services.