Skip to content

Conversation

@ilaflott
Copy link
Member

@ilaflott ilaflott commented Jan 22, 2025

this PR:

  • adds meta.yaml and build.sh to define the conda build package recipe
  • adds environment.yml defining fully functional conda environment inwhich mkmf should work
  • puts all bin/ executables under a nested mkmf "package" directory for conda build recipe compatibility
  • adds a github workflow file to run conda build under github's CI/CD pipelines, conda build . --no-anaconda-upload version in .github/workflows/build_conda.yml, with uploading in .github/workflows/publish_conda.yml. run conditions identical to that of fre-cli
  • removes some old unused files (.travis.yaml, .gitlab-ci.yml)
  • adjust success condition of some tests, e.g. list_paths prints version regex reflect recent version strings
  • adjusts how t/t001-list_paths.sh does set-up, now creates t/src/file6.f90 symbolic link on-the-fly. removed at end of each of those tests
  • adjusts how every test does setup- checks PATH and adjusts only if needed. above file6.f90 link creation done on-the-fly for t/t003-mkmf.sh as well.
  • tests and package should work in the usual way with the usual level of functioning for all desired contexts

ilaflott and others added 2 commits January 22, 2025 17:05
…define build recipe in meta.yaml and relevant fields. define conda environment.
@ilaflott
Copy link
Member Author

green check, yes. note failures in pipeline...

…for test step. add git at dependency to see if it keeps the pipeline happy.
@ilaflott ilaflott marked this pull request as ready for review January 23, 2025 19:19
@ilaflott
Copy link
Member Author

ilaflott commented Jan 23, 2025

current testing state is odd.

In the pipeline, t/t001-list_paths.sh tests fail, tests #'s 1, 3, 5, 6, and 7 (see copied pipeline output). But, locally on my workstation, only the first test, 1 list_paths prints version fails.

+ bats t/t001-list_paths.sh
+ echo 'failure guard :-('

not ok 1 list_paths prints version
# (in test file t/t001-list_paths.sh, line 19)
#   `[[ "$output" =~ ^list_paths\ [0-9]+\.[0-9]+$ ]]' failed

not ok 3 list_paths using default out file
# (in test file t/t001-list_paths.sh, line 32)
#   `[ "$(wc -l < path_names)" -eq 6 ]' failed


not ok 5 list_paths find files in t and test_* directories
# (in test file t/t001-list_paths.sh, line 44)
#   `[ "$(wc -l < path_names)" -eq 8 ]' failed

not ok 6 list_paths find specific files in t or test_* directories
# (in test file t/t001-list_paths.sh, line 51)
#   `[ "$(wc -l < path_names)" -eq 7 ]' failed

not ok 7 list_paths with specified out file
# (in test file t/t001-list_paths.sh, line 59)
#   `[ "$(wc -l < $outFileName)" = "6" ]' failed

Additionally, in the pipeline, all t/t002-git-version-string.sh tests fail, and yet locally on my workstation, all of these tests pass. I suppose i'm not entirely surprised by this because i've seen github's CI/CD has been weird about calling git commands directly in the past.

+ bats t/t002-git-version-string.sh
+ echo 'failure guard :-('

…move most unneeded failure-guarding shell commands.
…nge approach to resolving binDir in t/t001-list_paths- should possibly keep the pipeline happier. include mkmf in source files for test step of conda build. more echos, switch spot of echo output to avoid adjusting status of last-called shell command.
…he testing approach makes perfect sense locally- so why isnt the pipeline happy?
…tween string and ints in test success condition checks
…slowing this pipeline down for its own good!! (maybe...)
@ilaflott
Copy link
Member Author

AHA! the failure in githhub's pipeline arises because the command there, for some reason, resolves the symbolic link file file6.linked in t/src to file file6.f90 with one of the targeted extensions.

a little more simply: locally, the test list_paths using default out file in t/t001-list_paths.sh should ignore a link and only find 6 files. In github CI/CD, the symbolic link is resolved and it finds 7 files resulting in failure.

@ilaflott
Copy link
Member Author

relatively sure that once conda build . enters the test phase, the source_files key specifying t/ likely copies the directory with a command ala cp -L -r t/ <target_dir>, and is de-referencing the link to file6.f90, changing the answers in the list_files tests. i adjusted the answers accordingly, but this is honestly bad practice.

the git based tests in t still do not work in the pipeline but work fine for me locally.

@ceblanton
Copy link
Contributor

It looks great, thanks!

The noaa-gfdl channel is not needed for building, is it?

What do you think about throwing in the noaa-gfdl anaconda channel key and having this pipeline publish as well as build. Too soon?

It's odd that the tests needing adjusting (but then again I hadn't realized there were mkmf tests. :)

@ilaflott
Copy link
Member Author

ilaflott commented Jan 23, 2025

The noaa-gfdl channel is not needed for building, is it?

nope!

What do you think about throwing in the noaa-gfdl anaconda channel key and having this pipeline publish as well as build. Too soon?

no we can do it- i'll maybe say it should stick with an alpha version tag for now... at most, beta

It's odd that the tests needing adjusting (but then again I hadn't realized there were mkmf tests. :)

100% conda build is derefencing links found in specified source files for the testing step! idk what the best way to deal with that is and not lose true quality control.

put conda-relevant things in README- adjust markdown, update dependencies discussed. put disclaimer+license at the bottom of the readme to emphasize usage, installation, featurres etc.
update badge
@ilaflott
Copy link
Member Author

All tests now pass without caveat in all contexts.

@ilaflott ilaflott requested a review from singhd789 January 24, 2025 16:35
Copy link
Contributor

@ceblanton ceblanton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, Ian. Bonus for the the documentation updates.

The templates still have to be installed somehow, right?

@ilaflott
Copy link
Member Author

ilaflott commented Jan 24, 2025

Nice work, Ian. Bonus for the the documentation updates.

The templates still have to be installed somehow, right?

RE: these templates- mkmf needs you to specify a template target as an argument- i think. are these templates just supposed to be "found"? are they expected to be "nearby" ?

EDIT:
https://github.com/NOAA-GFDL/fre-cli/blob/a9730e039274739e5dc8710d82dcc09578735d18/fre/make/gfdlfremake/buildDocker.py#L31

@ceblanton
Copy link
Contributor

It's odd that mkmf includes the code and the templates for compiling FMS models on selected platforms, but they're been used together like this for 20 years.

I think it's a little more consistent to only conda install the mkmf and list-paths tools, but by tradition, we should probably include the templates in the conda package also.

CatalogBuilder does this.. I'm not sure how it works, but e.g. the templates are installed alongside the bin and lib files. @Ciheim could explain it. For proof though, the GFDL default template (gfdl_template.json) is installed in fre-cli:

c2b:/nbhome/fms/conda/envs/fre-test%>find . -name gfdl_template.json 

./lib/python3.9/site-packages/catalogbuilder/cats/gfdl_template.json

@ilaflott
Copy link
Member Author

It's odd that mkmf includes the code and the templates for compiling FMS models on selected platforms, but they're been used together like this for 20 years.

using shell to drive workflows for decades will incentivize this kind of approach. unfortunately, given the way conda packages function... do we really want to be doing things like this? targeting the templates/ dir within a conda environment i guess like:

mkmf -t /home/Ian.Laflotte/conda/envs/mkmf_test/......mkmf/templates

maybe we should consider de-coupling the templates and the code?

I think it's a little more consistent to only conda install the mkmf and list-paths tools, but by tradition, we should probably include the templates in the conda package also.

i'm sympathetic, i wanna figure it out.

CatalogBuilder does this.. I'm not sure how it works, but e.g. the templates are installed alongside the bin and lib files. @Ciheim could explain it. For proof though, the GFDL default template (gfdl_template.json) is installed in fre-cli:

c2b:/nbhome/fms/conda/envs/fre-test%>find . -name gfdl_template.json 

./lib/python3.9/site-packages/catalogbuilder/cats/gfdl_template.json

It's not quite 1-1: mkmf is not a python package and there is no pip install procedure here.

@ilaflott
Copy link
Member Author

catalogbuilder is using it's own pkg_dir property: https://github.com/search?q=repo%3ANOAA-GFDL%2FCatalogBuilder%20gfdl_template&type=code

i get the executables in the environment to $PREFIX/bin, because conda adds that to one's PATH for you. I could add a similar step where i cp mkmf/templates/* $PREFIX/lib or something. but fre-cli might have to do that pkg_dir path wrangling on it's own, and adjust the -t option, making the directory resolving fre make's problem to solve

@ilaflott
Copy link
Member Author

i think the ideal solution would be that
mkmf -t /absolute/or/relative/path/to/template.mk works as it does now, but e.g. specifying mkmf -t ncrc-gcc without the .mk extension says to mkmf "hey, get this template from your include dir".

@ceblanton
Copy link
Contributor

Yes!! I agree that would be a natural solution. I was thinking of a dummy list-templates tool to be added that reports the template directory but your idea is better.

@singhd789
Copy link

singhd789 commented Jan 24, 2025

Nice work, Ian. Bonus for the the documentation updates.
The templates still have to be installed somehow, right?

RE: these templates- mkmf needs you to specify a template target as an argument- i think. are these templates just supposed to be "found"? are they expected to be "nearby" ?

EDIT: https://github.com/NOAA-GFDL/fre-cli/blob/a9730e039274739e5dc8710d82dcc09578735d18/fre/make/gfdlfremake/buildDocker.py#L31

Pertaining to the templates for fre make functions, currently we have the path specified in the platforms.yaml:
https://github.com/NOAA-GFDL/fre-cli/blob/a9730e039274739e5dc8710d82dcc09578735d18/fre/make/tests/null_example/platforms.yaml#L6

Ryan mentioned this in another issue as well (in relation to mkmf being a submodule but still applies): NOAA-GFDL/fre-cli#303

If the template is in a set location in the conda package, that would pretty nice to refer to that location and just have the name of the template in the platforms.yaml (for fre make things at least)

@ilaflott
Copy link
Member Author

My main problem with me implementing that in this PR is that i do not know perl and am unsure if i'm the best person to implement that functionality on a short time-scale.

@ilaflott
Copy link
Member Author

Let's chat for a minute in-person on this when we can

@ilaflott
Copy link
Member Author

The templates should be a separate repository, as they're not really used by this repository out of necessity- they are a convenience for prospective users.

We're informing this view point with the following:

  1. all mkmf does with the value given to -t is stick the value as-is into the output Makefile, and the template is not read nor it's contents used programmatically by mkmf.
> mkmf -t FOO
. Makefile is ready.

> cat Makefile | grep TEMPLATE
MK_TEMPLATE = FOO
include $(MK_TEMPLATE)
  1. no one to our knowledge is relying on the templates in this repo as being in a particular spot directory-structure wise.

ilaflott and others added 4 commits January 28, 2025 11:42
slightly adjust current README instructions
test-run publish_conda workflow by asking it to run on push to `conda_package` branch, see what happens!
@ilaflott ilaflott closed this May 8, 2025
@ilaflott ilaflott reopened this Jun 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, mkmf isn't really touched that much I don't think...right? If it was at all, Mikyung had that really nice addition in the fre-cli build_conda script:
https://github.com/NOAA-GFDL/fre-cli/blob/main/.github/workflows/build_conda.yml#L8-L10

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not- but those bits that @mlee03 stuck in there are about redundant CI/CD workflows, not about the install. It's to use CI/CD minutes efficiently.

conda install conda-build conda-verify
# set token and upload preference
export ANACONDA_API_TOKEN=${{ secrets.ANACONDA_TOKEN }}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my own clarification, what were the token and secrets for again?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upload to the noaa-gfdl channel

Usage as a `conda` package requires `conda`.

For testing, we recommend [`bats-core`](https://github.com/bats-core/bats-core),
a current and up-to-date (as of January 2025) fork of the original

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like there was a new release as of May 18th

Kushner's suggestion).
Usage as a `conda` package requires `conda`.

For testing, we recommend [`bats-core`](https://github.com/bats-core/bats-core),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be nice to include what bats stands for (Bash Automated Testing System)..because I had no idea what it was 😅

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and maybe a quick little blurb about why it's recommended?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bats is standard bash testing infrastructure- given the link is there for a curious person to find bats-core doc with, i'm gonna disagree here.

and you're right, it's not recommended- it's required until someone comes up with something different for testing :-p.

git clone https://github.com/noaa-gfdl/mkmf.git mkmf && cd mkmf
conda env create -y -f ./environment.yaml
conda activate mkmf
export $PATH=$PWD/mkmf/bin:$PATH

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, why would it be necessary to add it to the path if there is a conda package for mkmf?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is like the "developer install" of fre-cli- local code responds to local edits, so add the local mkmf/bin to PATH.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit unrelated, but do you know if anyone has made a simplified conda packaging guide at the lab or is it really, just follow along with tutorials online?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is really good development, so I'm just curious

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

none that i know of. generally, we should be consulting official packaging guides and encouraging others to do so. we should be very cautious about writing our own packaging guides on top of the official ones- that invites some pretty nasty potential mistakes/misunderstandings

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... that being said i have some personal notes i can share that may shortcut you, just don't spread them around as a "packaging guide" :-p... follow up on that offline

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wholeheartedly agree, just wondering

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conda packaging is great candidate for the 5-10 minute MSD training topics, I agree.

I'm afraid yours truly attempted to do exactly this, building off of a Seth guide, as part of a conda MSD seminar a year or two ago, but the conda packaging parts were not that well-developed.

Copy link
Member

@underwoo underwoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some changes, or additional information needed.

requirements:
host:
- conda-forge::perl
- conda-forge::tcsh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tcsh is not used in any of the mkmf tools anymore. This dependency can be removed.

- conda-forge::bats-core
run:
- conda-forge::perl
- conda-forge::tcsh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No tcsh.

test:
requires:
- conda-forge::perl
- conda-forge::tcsh
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed.

binDir=$(readlink -f ${BATS_TEST_DIRNAME}/../mkmf/bin)
do_we_have_mkmf=$(which mkmf) || echo "no we do not!"
if [ $do_we_have_mkmf ]; then
echo 'likely conda case'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to make this more clear. I think I understand why this is done, but I could be wrong. Add comments or a better string to help someone who comes along later to know why this check is here.

Also, it is better to do something like:

if [ $(command -v mkmf) ]
then
    echo "mkmf already in PATH.  Not adding \"${binDir}\" to PATH."
else
    PATH=${binDir}:$PATH
fi
export PATH

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this more, I don't think you will want to do this check. This is a test to verify that the mkmf in the repository passes the tests. If mkmf is anywhere in PATH, even if the user adds their own copy, then the test will run that copy, and likely hide any issues the test will attempt to find. I strongly suggest removing this, unless you have a good reason otherwise.

# set PATH if needed
binDir=$(readlink -f ${BATS_TEST_DIRNAME}/../mkmf/bin)
do_we_have_mkmf=$(which mkmf) || echo "no we do not!"
if [ $do_we_have_mkmf ]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

}

teardown() {
rm -f ${BATS_TEST_DIRNAME}/src/file6.f90
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this file is in testDir, then you won't need this specific file removal.

[ "$status" -eq 0 ]
[ -e path_names ]
[ "$(wc -l < path_names)" -eq 6 ]
num_paths=$(cat path_names | wc -l)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider making a function to do this check.

# set PATH if needed
binDir=$(readlink -f ${BATS_TEST_DIRNAME}/../mkmf/bin)
do_we_have_mkmf=$(which mkmf) || echo "no we do not!"
if [ $do_we_have_mkmf ]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

# set PATH if needed
binDir=$(readlink -f ${BATS_TEST_DIRNAME}/../mkmf/bin)
do_we_have_mkmf=$(which mkmf) || echo "no we do not!"
if [ $do_we_have_mkmf ]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

# set PATH if needed
binDir=$(readlink -f ${BATS_TEST_DIRNAME}/../mkmf/bin)
do_we_have_mkmf=$(which mkmf) || echo "no we do not!"
if [ $do_we_have_mkmf ]; then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants