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]

Reply via email to