Skip to content

Automatically generate inputdata lists for container contents#33

Open
matthewhoffman wants to merge 13 commits into
mainfrom
inputdata-generator
Open

Automatically generate inputdata lists for container contents#33
matthewhoffman wants to merge 13 commits into
mainfrom
inputdata-generator

Conversation

@matthewhoffman

Copy link
Copy Markdown

Summary

This PR adds an end-to-end inputdata manifest generator and wires it into
automation so CI inputdata images can be updated from E3SM workflow definitions
without manual file curation.

What Changed

  • Added the initial generator scaffold and supporting helper modules.
  • Implemented workflow parsing to discover CI-relevant tests and standalone
    references from E3SM workflow configuration.
  • Added CIME-driven setup-only case processing to extract full-model inputdata
    references, including compatibility fixes and improved case attribution /
    failure diagnostics.
  • Added standalone discovery paths, including static discovery and config-mode
    artifact scanning.
  • Added URL normalization plus remote validation against public inputdata
    endpoints (e3sm & cesm), with explicit handling of unresolved files.
  • Added missing-file tracking output and repository plumbing so missing-file
    diffs are visible when they appear.
  • Added/update documentation describing generator behavior, inputs, outputs, and
    workflow integration.
  • Added automation to regenerate manifests and open PRs when inputdata lists change.

Resulting Behavior

  • Manifest generation now produces stable, reproducible outputs for:
    full-model files, standalone files, missing files, and provenance/state.
  • Missing server-side files are surfaced clearly instead of being silently lost.
  • Inputdata update automation is more signal-focused, reducing PR noise from
    metadata-only churn.

TLDR

CI will run weekly to:

  1. set up all cases (without build or data download) for all tests included in all
    files in .github/workflows
  2. create a list of all inputdata files from all of those tests
  3. check if that list differs from the current list; if so, automatically open a PR
    for committing the updated lists to main
  4. Once a human reviews and merges that PR, existing workflows will trigger to
    regenerate updated containers.

matthewhoffman and others added 13 commits July 8, 2026 20:27
Create a first working generator entrypoint under tools/inputdata with

deterministic output writing and strict-mode handling. Add helper modules

for workflow parsing, CIME list extraction, and URL normalization so

future iterations can refine behavior without changing CLI structure.
Clean up accidental py_compile outputs from the initial generator commit

and prevent recurrence by adding standard Python cache ignore patterns.
Replace placeholder standalone manifest entries with static scans of

EAMxx scripts/actions for check-input and inputdata-like file paths,

then normalize to public URLs and attach source-file provenance.
Run test-all-eamxx in best-effort config mode, scan generated artifacts

for inputdata references, and merge with static standalone discovery

while preserving deterministic output and warning/report behavior.
Track case directories created per test invocation to reduce cross-test

mixing, record start/finish timestamps, and include structured warning

fields to make generator failures easier to triage.
Introduce a new GitHub Actions workflow that regenerates inputdata

manifests on a weekly schedule and via manual workflow_dispatch, then

opens a pull request only when tracked manifest artifacts change.

This commit adds:

- .github/workflows/update-inputdata-manifest.yml

  - weekly cron + manual trigger

  - regenerate step using tools.inputdata.generate_inputdata_manifest

  - managed-file diff gate for conditional PR creation

  - concurrency guard and job timeout hardening

  - date-stamped branch naming for bot-created PRs

- tools/inputdata/build_pr_metadata.py

  - reusable helper that builds PR body markdown from git diff stats

    and e3sm-workflow-state metadata

- tools/inputdata/README.md

  - related-modules entry for the new metadata helper

The existing inputdata image build workflow remains separate and unchanged;

this new workflow handles manifest regeneration and PR creation only.
@matthewhoffman

Copy link
Copy Markdown
Author

@mahf708 , @rljacob , @bartgol , I tagged you all to review this, but I don't think all of you need to look at it closely. The basic idea is that it automates determining what inputdata needs to be included in the containers used for E3SM CI. It runs weekly and produces a list of all files needed for all tests in the workflows in the E3SM repo. If anything has changed, a PR in this repo is automatically opened to alert the team to the change. It also indicates if required files could not be found on either the e3sm or cesm servers. Once that is reviewed and merged, the updated file lists will trigger an existing workflow to regenerate the containers.

This improves on the current state where the inputdata preloaded into the containers may end up missing files (leading to CI downloading potentially large files every night...) or having unnecessary files (which may lead to the container hitting the GH runner size limit).

I've tested the file list generation piece in a container locally, and the results make sense to me. I have not tested the new workflow that would trigger a PR (because I didn't want to make a mess in this repo before you all looked at this), but I did lint the file locally. I also have not tested rebuilding the container with the resulting updated file lists to confirm that CI can run without needing to download any more data. I was hoping one of you, or someone else on the IG team, would be willing to do those steps (assuming you all think this is useful), because I'm not terribly familiar with how it all is supposed to work (esp. the standalone EAMxx testing workflow).

For the context, this idea was spawned by the CI failure we are seeing in the NGEE Arctic project, and the realization that we were downloading a lot of unnecessary data. This felt like the right upstream fix to solve our problem, and I hope E3SM Project finds this contribution useful. If not, that's ok too, we can always manage this on our own.

And, as is probably obvious, this was all written by copilot with guidance from me.

@mahf708 mahf708 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I reviewed this and I approve. I will wait a little before merging in case @rljacob or @bartgol have comments.

Two comments regarding the next steps (independent of this):

  1. we want to only generate the missing data for runners in the cloud (we also have runners that do stuff locally at SNL computers, for and for those we don't need to worry too much about data)
  2. one issue we may run into is... we will run out of space inside these containers :( some of the files needed/added for tests are way too huge and with gcam and other problems in E3SM repo, the repo itself is huge now... which means we are increasingly out of space... cloud-provided runners usually have little space in total

@bartgol

bartgol commented Jul 13, 2026

Copy link
Copy Markdown

This is a lot of stuff. I trust Naser review, as he is more knowledgeable than me regarding cloud/container testing.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces an automated inputdata manifest generator (driven by E3SM
workflow definitions) and wires it into a scheduled GitHub Actions workflow so
inputdata/ manifests can be refreshed and proposed via bot-opened PRs without
manual curation.

Changes:

  • Added a Python-based manifest generator that parses E3SM workflows, runs
    setup-only CIME create_test, and emits stable manifests plus provenance and
    missing-file outputs.
  • Added URL normalization + remote existence probing against E3SM/CESM public
    inputdata endpoints, with missing/unverified tracking.
  • Added a weekly update-inputdata-manifest workflow that regenerates outputs
    and opens a PR when the manifest trigger files change.

Reviewed changes

Copilot reviewed 10 out of 14 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tools/inputdata/README.md Documents generator purpose, inputs/outputs, and behavior.
tools/inputdata/generate_inputdata_manifest.py Implements end-to-end discovery pipeline, manifest writing, provenance/missing reporting.
tools/inputdata/build_pr_metadata.py Generates PR body content for bot-opened manifest update PRs.
tools/inputdata/lib/workflow_parser.py Extracts CI-relevant tests/standalone refs from E3SM workflow YAML.
tools/inputdata/lib/cime_manifest.py Runs setup-only create_test and parses Buildconf input list files.
tools/inputdata/lib/url_normalize.py Filters/normalizes candidate paths and constructs public inputdata URLs.
tools/inputdata/lib/inputdata_validation.py Probes candidate URLs (HEAD) and classifies resolution/missing/unverified.
tools/inputdata/init.py Declares the tools.inputdata package.
tools/inputdata/lib/init.py Declares the tools.inputdata.lib package.
.github/workflows/update-inputdata-manifest.yml Adds scheduled/manual automation to regenerate manifests and open PRs.
inputdata/files-missing.txt Adds managed output file for missing-inputdata tracking.
README.md Adds repository-level documentation for the workflows and automation.
.gitignore Ignores Python bytecode/cache artifacts.
readme Removes legacy/duplicate top-level readme stub.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/inputdata/README.md
Comment on lines +3 to +5
`tools/inputdata` contains the generator that builds the list of inputdata files required for Github
Continuous Integration tests. The purpose is to produce the files that should be included in the CI
Docker container, avoiding the need for them to be downloaded during CI.
Comment on lines +19 to +26
blocked_fragments = (
"baseline",
"rest",
"restart",
"history",
"output",
"archive",
)
Comment on lines +42 to +43
value = path_value.strip().strip('"').strip("'")
value = value.replace("\\", "/")
method="HEAD",
headers={"User-Agent": "Mozilla/5.0", "Accept-Encoding": "identity"},
)
context = ssl._create_unverified_context()
return InputDataValidationResult(
relative_path=relative_path,
checked_urls=(e3sm_url, cesm_url),
resolved_url=e3sm_url,
parser.add_argument(
"--strict",
action="store_true",
help="Fail if workflow parsing or standalone discovery emits warnings.",
provenance_record = ProvenanceRecord(
workflow=test_record.workflow,
test=test_record.name,
case_dir=test_record.name,
Comment on lines +222 to +224
for match in path_pattern.finditer(line):
raw = match.group("path")
candidates.add((file_path.as_posix(), raw))
Comment on lines +248 to +259
option_b_candidates = _scan_option_b_artifacts(e3sm_root, output_root) if option_b_ok else []
all_candidates = static_candidates + option_b_candidates
if not all_candidates:
return [], {}

for source_path, raw_path in all_candidates:
validation = _normalize_and_validate(raw_path, din_loc_root)
if not validation:
continue
method = "standalone-static"
if source_path.startswith(output_root.as_posix()) or "/ctest-build/" in source_path:
method = "standalone-config"
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.

4 participants