Skip to content

Commit 8802a98

Browse files
author
Michael Levin
committed
DO NOT MERGE: [Feature] Create script to do a one-off backload of API data for a given date, one day at a time until the present
- Allow deploy from bugfix branch and change command to the one-off backload task - Update script to be deployed to dev - Move backload dependencies to prod dependencies - Convert the async child process to resolve a promise - Make logging better by responding to child process events
1 parent 51c6688 commit 8802a98

File tree

6 files changed

+140
-10
lines changed

6 files changed

+140
-10
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ jobs:
5151
needs:
5252
- lint
5353
- test
54-
if: github.ref == 'refs/heads/develop'
55-
uses: 18F/analytics-reporter/.github/workflows/deploy.yml@develop
54+
if: github.ref == 'refs/heads/bugfix/backload_ga4_api_data'
55+
uses: 18F/analytics-reporter/.github/workflows/deploy.yml@bugfix/backload_ga4_api_data
5656
with:
5757
ANALYTICS_GA4_CALL_RETRY_COUNT: ${{ vars.ANALYTICS_GA4_CALL_RETRY_COUNT_DEV }}
5858
ANALYTICS_KEY_FILE_NAME: ${{ vars.ANALYTICS_KEY_FILE_NAME }}

deploy/api.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export ANALYTICS_SCRIPT_NAME=api.sh
66
# Gov Wide
77
$ANALYTICS_ROOT_PATH/bin/analytics --debug --write-to-database --output /tmp
88

9-
# Iterate over each agency config in deploy/envs
9+
# Iterate over each agency config
1010
for filename in $ANALYTICS_ROOT_PATH/deploy/envs/*.config.sh; do
1111
source $filename
1212
$ANALYTICS_ROOT_PATH/bin/analytics --debug --write-to-database --output /tmp

deploy/backload.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require("fs");
4+
const { program } = require("commander");
5+
const { formatISO, parseISO, differenceInDays, subDays } = require("date-fns");
6+
const apiReports = require("../reports/api.json");
7+
const { exec } = require("child_process");
8+
const logger = require("../src/logger").initialize();
9+
10+
/**
11+
* Script to backload DAP API data for a particular date.
12+
*
13+
* Example run command:
14+
* dotenv -e .env.analytics node -- ./backload.js --date 2024-01-01
15+
*/
16+
17+
program
18+
.option("-d, --date <string>", "date to run the backload for in ISO format")
19+
.option(
20+
"-e, --env <string>",
21+
"dotenv file to load for the process",
22+
".env.analytics",
23+
);
24+
25+
program.parse();
26+
27+
const options = program.opts();
28+
require("dotenv").config({ path: options.env });
29+
30+
const scriptRootPath = `${process.env.ANALYTICS_ROOT_PATH}/deploy`;
31+
32+
const runScriptWithLogName = async (scriptPath, scriptLoggingName) => {
33+
logger.info(`Beginning: ${scriptLoggingName}`);
34+
logger.info(`File path: ${scriptPath}`);
35+
const promise = new Promise((resolve) => {
36+
const childProcess = exec(scriptPath);
37+
childProcess.stdout.on("data", (data) => {
38+
console.log(data.toString().trim());
39+
});
40+
41+
childProcess.stderr.on("data", (data) => {
42+
console.log(data.toString().trim());
43+
});
44+
45+
childProcess.on("close", () => {
46+
resolve();
47+
});
48+
});
49+
50+
await promise;
51+
fs.unlinkSync("reports/api.json");
52+
fs.renameSync("reports/api.original.json", "reports/api.json");
53+
};
54+
55+
const api_run = () => {
56+
return runScriptWithLogName(`${scriptRootPath}/api.sh`, "api.sh");
57+
};
58+
59+
(async () => {
60+
logger.info("===========================================");
61+
logger.info("======= STARTING ANALYTICS-REPORTER =======");
62+
logger.info(`Running /deploy/backload.js for: ${options.date}`);
63+
logger.info("===========================================");
64+
65+
const scriptTargetDate = parseISO(options.date);
66+
const today = new Date();
67+
let totalDaysAgo = differenceInDays(today, scriptTargetDate);
68+
69+
while (totalDaysAgo >= 1) {
70+
const iterationTargetDate = subDays(new Date(), totalDaysAgo);
71+
72+
const iterationDaysAgo = differenceInDays(today, iterationTargetDate) + 1;
73+
const modifiedApiJsonString = JSON.stringify(apiReports)
74+
.replaceAll('"yesterday"', `"${iterationDaysAgo}daysAgo"`)
75+
.replaceAll('"3daysAgo"', `"${iterationDaysAgo}daysAgo"`);
76+
77+
fs.unlinkSync("reports/api.json");
78+
fs.writeFileSync("reports/api.original.json", JSON.stringify(apiReports));
79+
fs.writeFileSync("reports/api.json", modifiedApiJsonString);
80+
fs.writeFileSync("reports/api.new.json", modifiedApiJsonString);
81+
82+
logger.info(
83+
`Running API reports for ${formatISO(iterationTargetDate, { representation: "date" })}...`,
84+
);
85+
await api_run();
86+
totalDaysAgo = totalDaysAgo - 1;
87+
logger.info(
88+
`API reports for ${formatISO(iterationTargetDate, { representation: "date" })} complete`,
89+
);
90+
}
91+
})();

manifest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ applications:
1010
health-check-type: process
1111
buildpacks:
1212
- nodejs_buildpack
13-
command: node deploy/cron.js
13+
command: (node deploy/backload.js --date 2024-06-19 && echo SUCCESS || echo FAIL) && sleep infinity
1414
env:
1515
# This is a JSON string which has been base64 encoded
1616
ANALYTICS_CREDENTIALS: ${ANALYTICS_CREDENTIALS}

package-lock.json

Lines changed: 42 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@
7474
"googleapis": "^131.0.0",
7575
"minimist": "^1.2.8",
7676
"p-retry": "^6.2.0",
77-
"winston": "^3.11.0"
77+
"winston": "^3.11.0",
78+
"commander": "^12.1.0",
79+
"date-fns": "^3.6.0"
7880
},
7981
"devDependencies": {
8082
"@cucumber/cucumber": "^10.3.1",

0 commit comments

Comments
 (0)