Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"start": "npm run build && NODE_ENV=development webpack-dev-server --host 0.0.0.0 --open --hot --config build/webpack.config.js",
"build": "npm --prefix admin run build && NODE_ENV=production webpack --config build/webpack.config.js",
"serve": "cd src/server && NODE_ENV=development node app.js",
"lint": "eslint ."
"lint": "eslint .",
"test": "node --test \"test/**/*.test.js\""
},
"husky": {
"hooks": {
Expand Down
57 changes: 37 additions & 20 deletions src/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,33 @@ const app = express()
const proxy = require('http-proxy-middleware')
const path = require('path')

const configPath = './config.json'
const admindataPath = './admindata.json'
const dataPath = '../assets/data/data.json'
const logPath = '../assets/data/log.json'
const port = jsonfile.readFileSync(configPath).serverPort
const configBackupPath = '../../configBackup.json'
function resolvePathFromEnv(envName, defaultRelativeToCwd) {
if (process.env[envName]) {
return path.resolve(process.env[envName])
}
return path.resolve(process.cwd(), defaultRelativeToCwd)
}

const configPath = resolvePathFromEnv('LEADERBOARD_CONFIG_PATH', 'config.json')
const admindataPath = resolvePathFromEnv('LEADERBOARD_ADMINDATA_PATH', 'admindata.json')
const dataPath = resolvePathFromEnv('LEADERBOARD_DATA_PATH', '../assets/data/data.json')
const logPath = resolvePathFromEnv('LEADERBOARD_LOG_PATH', '../assets/data/log.json')
const configBackupPath = process.env.LEADERBOARD_CONFIG_BACKUP_PATH
? path.resolve(process.env.LEADERBOARD_CONFIG_BACKUP_PATH)
: path.resolve(process.cwd(), '../../configBackup.json')

const httpPort =
process.env.LEADERBOARD_PORT !== undefined && process.env.LEADERBOARD_PORT !== ''
? Number(process.env.LEADERBOARD_PORT)
: Number(jsonfile.readFileSync(configPath).serverPort)

const proxyOption = {
target: 'http://localhost:' + port + '/',
target: 'http://localhost:' + httpPort + '/',
pathRewrite: { '^/api': '' },
changeOrigin: true,
}
const websocketProxyOption = {
target: 'http://localhost:' + port + '/',
target: 'http://localhost:' + httpPort + '/',
changeOrigin: true,
}

Expand Down Expand Up @@ -54,17 +68,17 @@ if (!fs.existsSync(admindataPath)) {
jsonfile.writeFileSync(admindataPath, [])
}

// spawn - `node refresh.js`
const refresh = spawn('node', ['refresh.js'], {
shell: true,
stdio: 'inherit',
})
process.on('exit', () => {
refresh.kill() // kill it when exit
})
if (process.env.LEADERBOARD_SKIP_REFRESH !== '1') {
const refresh = spawn('node', ['refresh.js'], {
shell: true,
stdio: 'inherit',
})
process.on('exit', () => {
refresh.kill()
})
}

const server = http
.createServer((req, res) => {
const server = http.createServer((req, res) => {
const route = url.parse(req.url).pathname
const { adminPassword } = jsonfile.readFileSync(configPath)

Expand Down Expand Up @@ -109,7 +123,7 @@ const server = http
if (token === adminPassword) {
await Promise.all(
contributors.map(async (contributor) => {
const admindata = jsonfile.readFileSync('./admindata.json')
const admindata = jsonfile.readFileSync(admindataPath)
const existContributor = findContributor(
contributor,
admindata
Expand Down Expand Up @@ -408,7 +422,6 @@ const server = http
break
}
})
.listen(port)

const io = require('socket.io')(server)
io.on('connection', (socket) => {
Expand All @@ -423,6 +436,10 @@ io.on('connection', (socket) => {
})
})

server.listen(httpPort)

module.exports = { server }

function findContributor(contributorName, admindata) {
let result = null

Expand Down
8 changes: 7 additions & 1 deletion src/server/util/API.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
const axios = require('axios')
Copy link
Copy Markdown
Member

@Sing-Li Sing-Li Mar 27, 2026

Choose a reason for hiding this comment

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

@srijnabhargav "making it work with dotEnv" means absolutely NO CHANGES to the base code.

So please remove all changes to any file under src/server

And fix the tests so they work.

Thanks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry sir and thank you for the clarification. I have updated the PR

What was wrong earlier:

  • I had introduced test-related changes under src/server, which was not aligned with the already-merged dotenv support in master.
  • That was unnecessary because the upstream server already supports env-based path/config overrides such as CONFIG_PATH, DATA_PATH, LOG_PATH, ADMINDATA_PATH, CONFIG_BACKUP_PATH, and SERVER_PORT.

What I changed now:

  • Reverted the src/server changes so the PR does not rely on core code modifications.
  • Updated the regression test to use the existing upstream env/dotenv model from the test side only.
  • Kept the test isolated by wiring fixture paths through env vars and preventing the background refresh process from affecting the snapshot check.
  • Updated test/README.md with the exact install and test steps.

Validation: ran following commands

npm i
npm --prefix src/server install
npm test

Result: the regression test passes on the current upstream server code.

const Config = require('../config.json')
const chalk = require('chalk')
const path = require('path')

const Config = require(
process.env.LEADERBOARD_CONFIG_PATH
? path.resolve(process.env.LEADERBOARD_CONFIG_PATH)
: path.resolve(__dirname, '../config.json')
)

const BASEURL = 'https://github.com'
const APIHOST = 'https://api.github.com'
Expand Down
16 changes: 16 additions & 0 deletions test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Regression tests

This directory holds automated regression tests for stable leaderboard behavior.

`leaderboard-e2e.test.js` starts the current server code against a fixed Rocket.Chat snapshot and verifies that `/stats`, `/rank`, and selected `/contributor` and `/rank?username=` responses still match the checked-in expected output.

Fixtures:

- `../contrib/rocketchat/gsoc/2025/gsoc2025final.json` is the canonical snapshot used as the fixed leaderboard input.
- `fixtures/gsoc2025final.expected.json` is the checked-in golden output generated from the current stable ranking logic and used for regression comparisons.

Run from the repo root:

```bash
npm test
```
12 changes: 12 additions & 0 deletions test/fixtures/gsoc2025final.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"organization": "RocketChat",
"organizationHomepage": "https://rocket.chat/",
"organizationGithubUrl": "https://github.com/RocketChat",
"authToken": "",
"adminPassword": "123456",
"delay": "10",
"serverPort": "62050",
"contributors": [],
"startDate": "2024-12-01",
"includedRepositories": []
}
Loading