Thank you! Patch applied.
> On Nov 3, 2026, at 12:10 PM, Alastair McFarlane via dev > <[email protected]> wrote: > > Index: README_NEWTLP > =================================================================== > --- README_NEWTLP (revision 1940000) > +++ README_NEWTLP (working copy) > @@ -3,13 +3,23 @@ > 1. add the committee: > * create the committee RDF file in data/committees/ (copy > _template.rdf and edit it) > * link to the RDF file in data/committees.xml > -The script scripts/newtlp.py can be used to do the above: > +The script scripts/newtlp.py does both, from the committee-info.json entry: > > -* update site/create.html > -This can be done using scripts/update_create.py > + scripts/newtlp.py <pmc-id> [<pmc-id> ...] > > +It svn-adds the RDF file but does not commit. Check the diff it > prints, then commit. > +It cannot handle a committee coming back from the Attic. > + > 2. add projects managed by the committee: > -* create the project DOAP somewhere in the project SVN or Git space > -* add the DOAP location to data/projects.xml > +Project data comes from the ASF release catalog, which Apache Trusted > Releases > +builds from its own project records. ATR creates the committee itself > from LDAP, > +but not its projects: nothing here feeds them, so the PMC has to add > them in ATR. > +* a committee member uses Create project on the committee's page in ATR, or > +* the project: block of the repository's .asf.yaml creates it on the next > push. > +Until then the committee is listed here with a stub entry built from > +committees.json, and its page says the project is not yet in the catalog. > > +Project metadata is edited in ATR > (https://releases.apache.org/projects/<key>?tab=metadata) > +or in the project: metadata: block of .asf.yaml. > + > Data is not immediately reflected in https://projects.apache.org/: it > will be processed daily at 2 AM UTC > Index: scripts/cronjobs/parsecatalog.py > =================================================================== > --- scripts/cronjobs/parsecatalog.py (revision 1940000) > +++ scripts/cronjobs/parsecatalog.py (working copy) > @@ -40,8 +40,6 @@ > CATALOG_URL = 'https://release-catalog.apache.org/project_releases.json' > # Podlings are in a separate file, keyed by podling id > PODLING_CATALOG_URL = > 'https://release-catalog.apache.org/podling_releases.json' > -# ATR's project list carries status (active / retired / standing), > which the catalog lacks > -ATR_LIST_URL = 'https://releases.apache.org/api/projects/list' > > HOME = dirname(dirname(dirname(realpath(__file__)))) > SITE = join(HOME, 'site') > @@ -49,7 +47,6 @@ > PROJECTS_DIR = join(SITE, 'json', 'projects') > CACHE = join(HOME, 'data', 'cache', 'project_releases.json') > PODLING_CACHE = join(HOME, 'data', 'cache', 'podling_releases.json') > -ATR_CACHE = join(HOME, 'data', 'cache', 'atr_projects_list.json') > > # Fields projects.js treats as lists > LIST_FIELDS = {'category', 'programming-language', 'repository', > 'release', 'implements'} > @@ -94,23 +91,6 @@ > return data > > > -def fetch_atr_status(): > - """Return {key: status} from ATR. Falls back to the cached copy; > {} if none.""" > - try: > - req = urllib.request.Request(ATR_LIST_URL, > headers={'User-Agent': 'projects.apache.org'}) > - with urllib.request.urlopen(req, timeout=120) as r: > - data = json.loads(r.read().decode('utf-8')) > - if len(data.get('projects', [])) < 100: > - raise ValueError('ATR list looks truncated') > - os.makedirs(dirname(ATR_CACHE), exist_ok=True) > - with open(ATR_CACHE, 'w', encoding='utf-8') as f: > - json.dump(data, f) > - except Exception as e: > - print('WARN: could not fetch %s (%s); using cached copy' % > (ATR_LIST_URL, e)) > - data = load_json(ATR_CACHE, {}) > - return {p['key']: p.get('status') for p in data.get('projects', > []) if p.get('key')} > - > - > def as_list(v): > if v is None: > return [] > @@ -141,7 +121,6 @@ > args = ap.parse_args() > > catalog = fetch_catalog(args.file) > - atr_status = fetch_atr_status() > # Current podlings come from the podling catalog, as incubator-<id> > # (graduated/retired podlings are in it too; those are skipped) > podlings = load_json(join(FOUNDATION, 'podlings.json'), {}) or {} > @@ -179,10 +158,10 @@ > pmc = 'attic' > p['pmc'] = pmc > p['category'] = canonical(p.get('category'), valid_cats) > - status = atr_status.get(key) or ('retired' if pmc == 'attic' > else 'active') > + status = entry.get('status') or ('retired' if pmc == 'attic' > else 'active') > if pmc == 'attic': > status = 'retired' > - p['status'] = status # active / retired / > standing (from ATR) > + p['status'] = status # active / retired / standing > if status == 'retired' and 'retired' not in p['category']: > p['category'].append('retired') > p['programming-language'] = > canonical(p.get('programming-language'), valid_langs) > @@ -211,6 +190,9 @@ > if 'name' not in p: > warnings.append('%s: no name' % key) > > + if not any(isinstance(e, dict) and e.get('status') for e in > catalog.values()): > + warnings.append('catalog has no status field: every project > outside the attic is marked active') > + > # Committees with no catalog entry still need a stub, as > parseprojects.py did > have = {p['pmc'] for p in projects.values()} > for cid, c in committees.items(): > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
