Author: sebb
Date: Sat Jan 24 14:47:31 2026
New Revision: 1931513
Log:
Merge from trunk
Added:
comdev/reporter.apache.org/branches/tooling-project/data/releases/artemis.json
- copied unchanged from r1931512,
comdev/reporter.apache.org/trunk/data/releases/artemis.json
comdev/reporter.apache.org/branches/tooling-project/scripts/jira_auth.py
- copied unchanged from r1931512,
comdev/reporter.apache.org/trunk/scripts/jira_auth.py
Modified:
comdev/reporter.apache.org/branches/tooling-project/ (props changed)
comdev/reporter.apache.org/branches/tooling-project/DOCKER.md
comdev/reporter.apache.org/branches/tooling-project/Dockerfile
comdev/reporter.apache.org/branches/tooling-project/compose.yml
comdev/reporter.apache.org/branches/tooling-project/scripts/pdata.py
comdev/reporter.apache.org/branches/tooling-project/scripts/readjira.py
comdev/reporter.apache.org/branches/tooling-project/site/jiraversions.py
Modified: comdev/reporter.apache.org/branches/tooling-project/DOCKER.md
==============================================================================
--- comdev/reporter.apache.org/branches/tooling-project/DOCKER.md Sat Jan
24 14:40:12 2026 (r1931512)
+++ comdev/reporter.apache.org/branches/tooling-project/DOCKER.md Sat Jan
24 14:47:31 2026 (r1931513)
@@ -6,7 +6,15 @@
## Start application
-```docker compose up```
+You will need to provide credentials for Jira.
+The default user name is ```githubbot```.
+This can be overridden if you don't have its password.
+
+```
+export REPORTER_JIRA_USER=username
+export REPORTER_JIRA_PASSWORD=password
+docker compose up
+```
Browse to ```http://localhost/```
@@ -27,4 +35,14 @@ Gunicorn output to stdout
To start the app:
-```docker-config/start-reporter.sh```
+[Remember to provide the jira credentials!]
+
+```
+export REPORTER_JIRA_USER=username
+export REPORTER_JIRA_PASSWORD=password
+docker-config/start-reporter.sh
+```
+
+## stop the container and remove it
+
+```docker container down```
Modified: comdev/reporter.apache.org/branches/tooling-project/Dockerfile
==============================================================================
--- comdev/reporter.apache.org/branches/tooling-project/Dockerfile Sat Jan
24 14:40:12 2026 (r1931512)
+++ comdev/reporter.apache.org/branches/tooling-project/Dockerfile Sat Jan
24 14:47:31 2026 (r1931513)
@@ -15,9 +15,6 @@ RUN echo "ServerName reporter.local" > /
COPY docker-config/25-reporter.conf /etc/apache2/sites-enabled/000-default.conf
-WORKDIR /usr/local/etc/tokens
-RUN touch /usr/local/etc/tokens/jira.txt
-
WORKDIR /var/www/reporter.apache.org
EXPOSE 80
Modified: comdev/reporter.apache.org/branches/tooling-project/compose.yml
==============================================================================
--- comdev/reporter.apache.org/branches/tooling-project/compose.yml Sat Jan
24 14:40:12 2026 (r1931512)
+++ comdev/reporter.apache.org/branches/tooling-project/compose.yml Sat Jan
24 14:47:31 2026 (r1931513)
@@ -6,5 +6,8 @@ services:
volumes:
- .:/var/www/reporter.apache.org/
- ./docker-data/logs:/var/log/apache2
+ environment:
+ REPORTER_JIRA_USER: ${REPORTER_JIRA_USER:-githubbot}
+ REPORTER_JIRA_PASSWORD: ${REPORTER_JIRA_PASSWORD}
ports:
- 80:80
Copied:
comdev/reporter.apache.org/branches/tooling-project/data/releases/artemis.json
(from r1931512, comdev/reporter.apache.org/trunk/data/releases/artemis.json)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++
comdev/reporter.apache.org/branches/tooling-project/data/releases/artemis.json
Sat Jan 24 14:47:31 2026 (r1931513, copy of r1931512,
comdev/reporter.apache.org/trunk/data/releases/artemis.json)
@@ -0,0 +1,3 @@
+{
+ "Artemis 2.50.0": 1769126400
+}
\ No newline at end of file
Copied:
comdev/reporter.apache.org/branches/tooling-project/scripts/jira_auth.py (from
r1931512, comdev/reporter.apache.org/trunk/scripts/jira_auth.py)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ comdev/reporter.apache.org/branches/tooling-project/scripts/jira_auth.py
Sat Jan 24 14:47:31 2026 (r1931513, copy of r1931512,
comdev/reporter.apache.org/trunk/scripts/jira_auth.py)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python3
+"""
+Common code for handling Jira authentication
+
+INITIAL RELEASE: include more common code later
+"""
+
+import os
+
+JIRA_USER = os.environ.get('REPORTER_JIRA_USER', 'githubbot')
+jirapass = os.environ.get('REPORTER_JIRA_PASSWORD', '')
+if jirapass == '':
+ with open("/usr/local/etc/tokens/jira.txt", "r", encoding='utf-8') as f:
+ jirapass = f.read().strip()
+if jirapass == '':
+ raise RuntimeError("Jira password cannot be empty")
+JIRA_PASS = jirapass
Modified: comdev/reporter.apache.org/branches/tooling-project/scripts/pdata.py
==============================================================================
--- comdev/reporter.apache.org/branches/tooling-project/scripts/pdata.py
Sat Jan 24 14:40:12 2026 (r1931512)
+++ comdev/reporter.apache.org/branches/tooling-project/scripts/pdata.py
Sat Jan 24 14:47:31 2026 (r1931513)
@@ -29,6 +29,9 @@ CACHE_TIMEOUT = 7200
import committee_info
from urlutils import UrlCache
+sys.path.append(".") # module is in current directory
+import jira_auth
+
# This script may be called frequently, so don't just rely on IfNewer checks
uc = UrlCache(cachedir='../data/cache', interval=CACHE_TIMEOUT, silent=True)
@@ -62,10 +65,6 @@ ldapmap = {
'webservices': 'ws'
}
-jirapass = ""
-with open("/usr/local/etc/tokens/jira.txt", "r") as jf:
- jirapass = jf.read().strip()
-
def readJson(filename, *default):
"""Read a JSON file. If the read fails, return the default (if any)
otherwise return the exception"""
data = {}
@@ -125,9 +124,9 @@ def getJIRAProjects(project, tlpid):
x = readJson(RAOHOME+"data/JIRA/jira_projects.json")
else:
if sys.version_info >= (3, 0):
- base64string = base64.encodebytes(('%s:%s' % ('githubbot',
jirapass)).encode('ascii')).decode('ascii')[:-1]
+ base64string = base64.encodebytes(('%s:%s' %
(jira_auth.JIRA_USER,
jira_auth.JIRA_PASS)).encode('ascii')).decode('ascii')[:-1]
else:
- base64string = base64.encodebytes('%s:%s' % ('githubbot',
jirapass))[:-1]
+ base64string = base64.encodebytes('%s:%s' %
(jira_auth.JIRA_USER, jira_auth.JIRA_PASS))[:-1]
try:
x =
requests.get("https://issues.apache.org/jira/rest/api/2/project.json", headers
= {"Authorization": "Basic %s" % base64string}).json()
@@ -174,9 +173,9 @@ def getJIRAS(project):
pass
if refresh:
if sys.version_info >= (3, 0):
- base64string = base64.encodebytes(('%s:%s' % ('githubbot',
jirapass)).encode('ascii')).decode('ascii')[:-1]
+ base64string = base64.encodebytes(('%s:%s' % (jira_auth.JIRA_USER,
jira_auth.JIRA_PASS)).encode('ascii')).decode('ascii')[:-1]
else:
- base64string = base64.encodebytes('%s:%s' % ('githubbot',
jirapass))[:-1]
+ base64string = base64.encodebytes('%s:%s' % (jira_auth.JIRA_USER,
jira_auth.JIRA_PASS))[:-1]
try:
headers = {"Authorization": "Basic %s" % base64string}
req =
requests.get("""https://issues.apache.org/jira/rest/api/2/search?jql=project%20=%20'"""
+ project + """'%20AND%20created%20%3E=%20-91d""", headers = headers)
Modified:
comdev/reporter.apache.org/branches/tooling-project/scripts/readjira.py
==============================================================================
--- comdev/reporter.apache.org/branches/tooling-project/scripts/readjira.py
Sat Jan 24 14:40:12 2026 (r1931512)
+++ comdev/reporter.apache.org/branches/tooling-project/scripts/readjira.py
Sat Jan 24 14:47:31 2026 (r1931513)
@@ -21,6 +21,9 @@ from os import listdir
from os.path import isfile, join, dirname, abspath
from inspect import getsourcefile
+sys.path.append(".") # module is in current directory
+import jira_auth
+
# MYHOME = "/var/www/reporter.apache.org"
# Assume we are one directory below RAO (scripts)
MYHOME = dirname(dirname(abspath(getsourcefile(lambda:0)))) # automatically
work out home location so can run the code anywhere
@@ -36,11 +39,6 @@ mypath = "%s/data/JIRA" % MYHOME
print("Scanning mypath=%s" % mypath)
myfiles = [ f for f in listdir(mypath) if f.endswith(".json") and
isfile(join(mypath,f)) ]
-jirapass = ""
-with open("/usr/local/etc/tokens/jira.txt", "r") as f:
- jirapass = f.read().strip()
- f.close()
-
JIRA_SLEEP = 0.5 # how long to wait between API requests
JIRATIMEOUT=90 # This may need to be adjusted
jiraerrors = 0 # count how many consecutive errors occurred
@@ -56,7 +54,7 @@ def handleError():
def getCookie():
hdrs = {"content-type": "application/json"}
- data = {"username": "githubbot", "password": jirapass } # needs to be JSON
+ data = {"username": jira_auth.JIRA_USER, "password": jira_auth.JIRA_PASS }
# needs to be JSON
res = requests.post(JIRA_AUTH, headers=hdrs, json=data,
timeout=JIRATIMEOUT)
# Show more detail for login failures
if res.status_code in [401, 403]:
Modified:
comdev/reporter.apache.org/branches/tooling-project/site/jiraversions.py
==============================================================================
--- comdev/reporter.apache.org/branches/tooling-project/site/jiraversions.py
Sat Jan 24 14:40:12 2026 (r1931512)
+++ comdev/reporter.apache.org/branches/tooling-project/site/jiraversions.py
Sat Jan 24 14:47:31 2026 (r1931513)
@@ -10,6 +10,7 @@ import os, sys, json, urllib2, time, bas
sys.path.append("../scripts") # module is in sibling directory
import ldap_info
+import jira_auth
form = cgi.FieldStorage()
user = os.environ['HTTP_X_AUTHENTICATED_USER'] if 'HTTP_X_AUTHENTICATED_USER'
in os.environ else None
@@ -34,14 +35,10 @@ def getReleaseData(project):
except:
return {}
-jirapass = ""
-with open("/usr/local/etc/tokens/jira.txt", "r") as f:
- jirapass = f.read().strip()
-
# Do the cheapest checks first
if jiraname and user and (ldap_info.isMember(user) or project in
ldap_info.getPMCownership(user)):
jiraname = jiraname.upper()
- base64string = base64.encodestring('%s:%s' % ('githubbot', jirapass))[:-1]
+ base64string = base64.encodestring('%s:%s' % (jira_auth.JIRA_USER,
jira_auth.JIRA_PASS))[:-1]
try:
req =
urllib2.Request("https://issues.apache.org/jira/rest/api/2/project/%s/versions"
% jiraname)
req.add_header("Authorization", "Basic %s" % base64string)