Skip to content

Commit

Permalink
fix: check db integrity after building it (#753)
Browse files Browse the repository at this point in the history
We didn't check if the static Elm database built was valid, allowing
deploying to production a broken app. 

Let's introduce a script to check the build database integrity.
  • Loading branch information
n1k0 authored Sep 17, 2024
1 parent a57dbf9 commit 5b41ef6
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 6 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ jobs:
- name: Build app
run: npm run build --if-present

- name: Build Elm static Db
run: npm run db:build

- name: Run prettier, openapi & ruff formatting check
run: npm run lint:all

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/.env
/dist
elm-stuff
/check-db-app.js
/compute-aggregated-app.js
/node_modules
/public/app.js
Expand Down
30 changes: 30 additions & 0 deletions check-db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require("dotenv").config();
const fs = require("fs");
const { Elm } = require("./check-db-app");
const lib = require("./lib");

const { ECOBALYSE_DATA_DIR } = process.env;

let dataFiles;
try {
dataFiles = lib.getDataFiles(ECOBALYSE_DATA_DIR);
} catch (err) {
console.error(`🚨 ERROR: ${err.message}`);
process.exit(1);
}

const elmApp = Elm.CheckDb.init({
flags: {
textileProcesses: fs.readFileSync(dataFiles.textileDetailed, "utf-8"),
foodProcesses: fs.readFileSync(dataFiles.foodDetailed, "utf-8"),
},
});

elmApp.ports.logAndExit.subscribe(({ message, status }) => {
if (status > 0) {
console.error(`🚨 ERROR: ${message}`);
} else {
console.info(message);
}
process.exit(status);
});
2 changes: 1 addition & 1 deletion compute-aggregated.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ elmApp.ports.export.subscribe(
exportJson(dataFiles.foodNoDetails, foodProcessesOnlyAggregated);
console.log(`
4 files exported to:
x"
- ${dataFiles.textileDetailed}
- ${dataFiles.foodDetailed}
- ${dataFiles.textileNoDetails}
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
"build": "npm run server:build && rimraf dist && npm run build:init && parcel build index.html --public-url ./",
"build:init": "./bin/update-version.sh && mkdir -p dist && cp -r public/* dist/ && npm run db:build",
"build:standalone-app": "npm run build && npm run server:build && cp server-app.js dist/ && cp openapi.yaml dist/",
"processes:build": "elm make src/ComputeAggregated.elm --output=compute-aggregated-app.js && node compute-aggregated.js",
"decrypt": "./bin/decrypt",
"encrypt": "./bin/encrypt",
"db:build": "./bin/build-db",
"db:build": "./bin/build-db && npm run db:check",
"db:check": "elm make src/CheckDb.elm --optimize --output=check-db-app.js 1> /dev/null && node check-db.js",
"lint:openapi": "npx swagger-cli validate openapi.yaml",
"lint:prettier": "prettier --config .prettierrc --check",
"lint:prettier:all": "npm run lint:prettier -- .",
Expand All @@ -34,6 +34,7 @@
"fix:ruff:format": "pipenv run ruff format --force-exclude",
"fix:all": "npm run fix:ruff:all && npm run fix:prettier:all",
"format:json": "npx [email protected] --write . && pipenv run ruff check --select I --fix && pipenv run ruff format",
"processes:build": "elm make src/ComputeAggregated.elm --output=compute-aggregated-app.js 1> /dev/null && node compute-aggregated.js",
"server:build": "npm run db:build && elm make src/Server.elm --optimize --output=server-app.js",
"server:dev": "npm run server:build && nodemon server.js --config nodemon.json",
"server:debug": "elm make src/Server.elm --output=server-app.js && nodemon server.js --config nodemon.json",
Expand Down
45 changes: 45 additions & 0 deletions src/CheckDb.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
port module CheckDb exposing (main)

import Static.Db as StaticDb exposing (Db)
import Static.Json as StaticJson


type alias Flags =
{ foodProcesses : String
, textileProcesses : String
}


init : Flags -> ( (), Cmd () )
init flags =
( ()
, case checkStaticDatabases flags of
Err error ->
logAndExit { message = error, status = 1 }

Ok _ ->
logAndExit { message = "Dbs look fine", status = 0 }
)


checkStaticDatabases : Flags -> Result String ( Db, Db )
checkStaticDatabases detailedRawJsonProcesses =
Result.map2 Tuple.pair
(StaticDb.db StaticJson.rawJsonProcesses
|> Result.mapError (\err -> "Non-detailed Db is invalid: " ++ err)
)
(StaticDb.db detailedRawJsonProcesses
|> Result.mapError (\err -> "Detailed Db is invalid: " ++ err)
)


main : Program Flags () ()
main =
Platform.worker
{ init = init
, subscriptions = always Sub.none
, update = \_ _ -> ( (), Cmd.none )
}


port logAndExit : { message : String, status : Int } -> Cmd msg

0 comments on commit 5b41ef6

Please sign in to comment.