This is an automated email from the ASF dual-hosted git repository.

rzo1 pushed a commit to branch team-site-update
in repository https://gitbox.apache.org/repos/asf/opennlp-site.git

commit 143df97114b07bd60d2fbaf4c0761e83ed2d4fb2
Author: Richard Zowalla <[email protected]>
AuthorDate: Thu Apr 30 14:22:35 2026 +0200

    Add --no-fetch flag and document team-overrides.properties
    
    The team page build can now skip the live GitHub + Whimsy retrieval 
entirely,
    for offline/restricted environments where api.github.com or 
whimsy.apache.org
    is unreachable. Triggered three ways:
    
      mvn compile -Pno-fetch                # Maven profile
      ... -DopennlpSiteNoFetch ...          # n/a; use the env var or profile
      OPENNLP_SITE_NO_FETCH=1 mvn compile   # env var
      Site ... --no-fetch                   # CLI flag
    
    When set, Contributors.empty() returns three empty section lists instead of
    calling out to the network; the team page renders with "No contributors to
    show." placeholders, and the rest of the site builds normally.
    
    README also gains a "Manual roster overrides" subsection documenting the
    src/main/resources/team-overrides.properties keys (.gh, .status, .chair),
    including an example, plus a "Skipping the live fetch" subsection covering
    the new -Pno-fetch profile and the env var equivalent.
---
 README.md                                          | 34 +++++++++++++++++++++-
 pom.xml                                            | 32 ++++++++++++++++++++
 src/main/java/org/apache/opennlp/website/Site.java | 19 ++++++++++--
 .../opennlp/website/contributors/Contributors.java |  5 ++++
 4 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 5f1bc14f8..4d5f4e4e1 100644
--- a/README.md
+++ b/README.md
@@ -55,10 +55,42 @@ The team page (`team.html`) is populated at build time by 
the `org.apache.opennl
 - the OpenNLP committer/PMC roster from [Whimsy LDAP 
exports](https://whimsy.apache.org/public/), and
 - live contributor + activity data from the GitHub REST API across 
`apache/opennlp`, `apache/opennlp-site`, `apache/opennlp-addons` and 
`apache/opennlp-sandbox`.
 
-It then partitions members into **Active Team** (any activity in the last 2 
years), **Emeritus** (committer/PMC with no recent activity) and a **Wall of 
Fame** (everyone with a GitHub login). Identity merging (login + apache id + 
email + normalized name) and bot filtering match the logic of the 
`opennlp-stats` reference tool.
+It then partitions members into **Active Team** (any activity in the last 2 
years), **Emeritus** (committer/PMC with no recent activity) and a **Wall of 
Fame** (everyone else with a GitHub login — committers/PMCs aren't repeated 
here). Identity merging (login + apache id + email + normalized name) and bot 
filtering match the logic of the `opennlp-stats` reference tool.
 
 HTTP responses are cached on disk under `target/contrib-cache/` with a 6-hour 
TTL, so iterative local builds are cheap. The build runs without a GitHub 
token; anonymous rate limits (60 req/h) may leave a few `/users/{login}` 
lookups unresolved on a cold cache, which can drop a committer whose GitHub 
login differs from their Apache id into Emeritus until the cache warms. 
Re-running the build inside the TTL fills it in.
 
+##### Manual roster overrides
+
+Whimsy doesn't always carry `githubUsername` for committers, and the live 
`/users/{login}` bridge can hit anonymous rate limits, so 
`src/main/resources/team-overrides.properties` lets you pin attributes per 
Apache id. The file is read at build time and merged on top of the Whimsy + 
GitHub data.
+
+| Key | Meaning |
+| --- | --- |
+| `<apacheId>.gh` | One or more `;`-separated GitHub logins. The first is used 
for the card link and avatar; the rest are merged into the same record so their 
commits/PRs/comments roll up. |
+| `<apacheId>.status` | `active` or `emeritus`. Forces the section bucket 
regardless of what the live activity check says. |
+| `<apacheId>.chair` | `true` for the current PMC chair. Renders an extra 
orange `Chair` badge on the card and adds the chair entry to the legend. |
+
+Example:
+
+```properties
+jzemerick.gh     = jzonthemtn
+jzemerick.status = active
+jzemerick.chair  = true
+
+joern.gh         = kottmann
+joern.status     = active
+```
+
+##### Skipping the live fetch (offline / restricted CI)
+
+If the build environment can't reach `api.github.com` or `whimsy.apache.org` — 
corporate proxy, blocked CI runner, demo build — skip the retrieval entirely:
+
+```bash
+mvn compile -Pno-fetch          # Maven profile
+OPENNLP_SITE_NO_FETCH=1 mvn compile   # env var (any non-empty truthy value)
+```
+
+The team page renders with empty Active/Emeritus/Wall-of-Fame sections (each 
shows a "No contributors to show." placeholder); the rest of the site builds 
normally.
+
 #### Build Bot
 
 Website is built via ASF BuildBot. You find it [here](https://ci.apache.org/).
diff --git a/pom.xml b/pom.xml
index 88775482e..c676accce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -701,6 +701,38 @@
         </plugins>
       </build>
     </profile>
+
+    <!-- mvn compile -Pno-fetch  ->  skip the live GitHub + Whimsy retrieval 
entirely.
+         Use this when network egress to api.github.com / whimsy.apache.org is 
blocked
+         (corporate proxy, restricted CI runner, offline build). The team page 
renders
+         with empty Active/Emeritus/Wall-of-Fame sections; everything else 
builds
+         normally. The same can be triggered with -DopennlpSiteNoFetch=true or 
by
+         exporting OPENNLP_SITE_NO_FETCH=1 in the build environment. -->
+    <profile>
+      <id>no-fetch</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>exec-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>opennlp-site</id>
+                <configuration>
+                  <arguments>
+                    <argument>${project.basedir}/src/main/jbake</argument>
+                    
<argument>${project.build.directory}/${project.build.finalName}</argument>
+                    
<argument>${project.build.directory}/jbake-staged</argument>
+                    
<argument>${project.build.directory}/contrib-cache</argument>
+                    <argument>--no-fetch</argument>
+                  </arguments>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
   </profiles>
 
 </project>
diff --git a/src/main/java/org/apache/opennlp/website/Site.java 
b/src/main/java/org/apache/opennlp/website/Site.java
index a3be4f324..6e1a91497 100644
--- a/src/main/java/org/apache/opennlp/website/Site.java
+++ b/src/main/java/org/apache/opennlp/website/Site.java
@@ -58,7 +58,7 @@ public final class Site {
     public static void main(final String[] args) throws Exception {
         if (args.length < 4) {
             throw new IllegalArgumentException(
-                    "usage: Site <source> <dest> <staged> <cache> [--serve] 
[--port=N]");
+                    "usage: Site <source> <dest> <staged> <cache> [--serve] 
[--port=N] [--no-fetch]");
         }
         final Path source = Path.of(args[0]);
         final Path dest = Path.of(args[1]);
@@ -66,15 +66,28 @@ public final class Site {
         final Path cacheDir = Path.of(args[3]);
 
         boolean serve = false;
+        boolean noFetch = false;
         int port = 8080;
         for (int i = 4; i < args.length; i++) {
             final String a = args[i];
             if (a.equals("--serve")) serve = true;
+            else if (a.equals("--no-fetch")) noFetch = true;
             else if (a.startsWith("--port=")) port = 
Integer.parseInt(a.substring("--port=".length()));
         }
+        // Env-var fallback so CI can flip the switch without touching pom 
args.
+        if (!noFetch) {
+            final String env = System.getenv("OPENNLP_SITE_NO_FETCH");
+            noFetch = env != null && (env.equals("1") || 
env.equalsIgnoreCase("true"));
+        }
 
-        System.out.println("[site] fetching contributor data...");
-        final Contributors.Sections sections = Contributors.load(cacheDir);
+        final Contributors.Sections sections;
+        if (noFetch) {
+            System.out.println("[site] --no-fetch: skipping live GitHub + 
Whimsy retrieval");
+            sections = Contributors.empty();
+        } else {
+            System.out.println("[site] fetching contributor data...");
+            sections = Contributors.load(cacheDir);
+        }
         System.out.printf("[site] active=%d emeritus=%d wall-of-fame=%d%n",
                 sections.active().size(), sections.emeritus().size(), 
sections.wallOfFame().size());
 
diff --git 
a/src/main/java/org/apache/opennlp/website/contributors/Contributors.java 
b/src/main/java/org/apache/opennlp/website/contributors/Contributors.java
index 64c57083c..d9edb3461 100644
--- a/src/main/java/org/apache/opennlp/website/contributors/Contributors.java
+++ b/src/main/java/org/apache/opennlp/website/contributors/Contributors.java
@@ -35,6 +35,11 @@ public final class Contributors {
 
     public record Sections(List<Contributor> active, List<Contributor> 
emeritus, List<Contributor> wallOfFame) {}
 
+    /** No-network fallback used by --no-fetch / OPENNLP_SITE_NO_FETCH. */
+    public static Sections empty() {
+        return new Sections(List.of(), List.of(), List.of());
+    }
+
     public static Sections load(final Path cacheDir) throws Exception {
         final String token = System.getenv("GITHUB_TOKEN");
         final HttpCache cache = new HttpCache(cacheDir, Duration.ofHours(6), 
token);

Reply via email to