Added build script.
This commit is contained in:
parent
9d1712889e
commit
e0edfb8d68
|
@ -0,0 +1 @@
|
|||
build/
|
|
@ -0,0 +1,150 @@
|
|||
#!/usr/bin/env rdmd
|
||||
/**
|
||||
* A simple build script that builds all Gymboard applications and collects
|
||||
* build artifacts for deployment. You can run it with `./build_apps.d`, and it
|
||||
* will build each application for production deployment using a separate
|
||||
* thread.
|
||||
*
|
||||
* Supply the "clean" command to remove all build artifacts instead of building.
|
||||
*/
|
||||
module build_apps;
|
||||
|
||||
import std.stdio;
|
||||
import std.process;
|
||||
import std.file;
|
||||
import std.path;
|
||||
import std.regex;
|
||||
import core.thread;
|
||||
|
||||
enum BUILDS_DIR = "build";
|
||||
|
||||
int main(string[] args) {
|
||||
if (args.length > 1 && args[1] == "clean") {
|
||||
rmdirRecurse(BUILDS_DIR);
|
||||
return 0;
|
||||
}
|
||||
Thread[] buildThreads = [
|
||||
runBuildInThread(API_BUILD_SPEC),
|
||||
runBuildInThread(CDN_BUILD_SPEC),
|
||||
runBuildInThread(SEARCH_BUILD_SPEC),
|
||||
runBuildInThread(APP_BUILD_SPEC),
|
||||
runBuildInThread(UPLOADS_BUILD_SPEC)
|
||||
];
|
||||
|
||||
foreach (t; buildThreads) t.join();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specification for building an application.
|
||||
*/
|
||||
struct BuildSpec {
|
||||
string name;
|
||||
string workingDir;
|
||||
string buildCommand;
|
||||
typeof(ctRegex!(`\d`)) artifactRegex;
|
||||
}
|
||||
|
||||
static immutable API_BUILD_SPEC = BuildSpec(
|
||||
"api",
|
||||
"gymboard-api",
|
||||
"./mvnw clean package spring-boot:repackage",
|
||||
ctRegex!(`target/gymboard-api-.*\.jar$`)
|
||||
);
|
||||
|
||||
static immutable CDN_BUILD_SPEC = BuildSpec(
|
||||
"cdn",
|
||||
"gymboard-cdn",
|
||||
"./mvnw clean package spring-boot:repackage",
|
||||
ctRegex!(`target/gymboard-cdn-.*\.jar$`)
|
||||
);
|
||||
|
||||
static immutable SEARCH_BUILD_SPEC = BuildSpec(
|
||||
"search",
|
||||
"gymboard-search",
|
||||
"./mvnw clean package spring-boot:repackage -DskipTests=true",
|
||||
ctRegex!(`target/gymboard-search-.*\.jar$`)
|
||||
);
|
||||
|
||||
static immutable APP_BUILD_SPEC = BuildSpec(
|
||||
"app",
|
||||
"gymboard-app",
|
||||
"quasar build",
|
||||
ctRegex!(`gymboard-app/dist$`)
|
||||
);
|
||||
|
||||
static immutable UPLOADS_BUILD_SPEC = BuildSpec(
|
||||
"uploads",
|
||||
"gymboard-uploads",
|
||||
"dub build --build=release",
|
||||
ctRegex!(`gymboard-uploads/gymboard-uploads$`)
|
||||
);
|
||||
|
||||
/**
|
||||
* Runs a build and returns its exit code.
|
||||
* Params:
|
||||
* spec = The build spec to run.
|
||||
* Returns: The exit code of the build. 0 indicates success.
|
||||
*/
|
||||
int runBuild(const BuildSpec spec) {
|
||||
string buildDir = buildPath(BUILDS_DIR, spec.name);
|
||||
if (exists(buildDir)) rmdirRecurse(buildDir);
|
||||
mkdirRecurse(buildDir);
|
||||
File buildLogFile = File(buildPath(buildDir, "build.log"), "w");
|
||||
File buildErrorLogFile = File(buildPath(buildDir, "build-error.log"), "w");
|
||||
Pid pid = spawnShell(
|
||||
spec.buildCommand,
|
||||
std.stdio.stdin,
|
||||
buildLogFile,
|
||||
buildErrorLogFile,
|
||||
null,
|
||||
Config.none,
|
||||
spec.workingDir,
|
||||
nativeShell()
|
||||
);
|
||||
int result = wait(pid);
|
||||
if (result != 0) return result;
|
||||
|
||||
// Find and extract artifacts.
|
||||
bool artifactFound = false;
|
||||
foreach (DirEntry entry; dirEntries(spec.workingDir, SpanMode.breadth, false)) {
|
||||
Captures!string c = matchFirst(entry.name, spec.artifactRegex);
|
||||
if (!c.empty) {
|
||||
artifactFound = true;
|
||||
string destFilename = buildPath(buildDir, baseName(entry.name));
|
||||
writefln!"Copying artifact %s to %s"(entry.name, destFilename);
|
||||
if (entry.isFile) {
|
||||
writefln!" Filesize: %d"(entry.size);
|
||||
copy(entry.name, destFilename);
|
||||
} else if (entry.isDir) {
|
||||
Pid cpPid = spawnShell("cp -R " ~ entry.name ~ " " ~ destFilename);
|
||||
int cpResult = wait(cpPid);
|
||||
if (cpResult != 0) {
|
||||
writefln!"Failed to copy directory: %d"(cpResult);
|
||||
return cpResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!artifactFound) {
|
||||
writefln!"Warning: Build %s completed successfully, but no matching artifacts were found."(spec.name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps building of a build spec in a thread.
|
||||
* Params:
|
||||
* spec = The spec to build.
|
||||
* Returns: The thread running the build, which is already started.
|
||||
*/
|
||||
Thread runBuildInThread(const BuildSpec spec) {
|
||||
Thread t = new Thread(() {
|
||||
writefln!"Building \"%s\" in %s"(spec.name, spec.workingDir);
|
||||
int result = runBuild(spec);
|
||||
writefln!"Build \"%s\" exited with code %d."(spec.name, result);
|
||||
});
|
||||
t.start();
|
||||
return t;
|
||||
}
|
|
@ -18,3 +18,5 @@ Therefore, **gymboard-uploads** is responsible for the following actions:
|
|||
- Processing of raw videos to reduce file size and optimize for web. This will most likely be done using FFMPEG in the backend.
|
||||
- Reporting the status of video processing for recently uploaded videos.
|
||||
- Serving processed video files.
|
||||
|
||||
**THIS PROJECT IS A WORK-IN-PROGRESS** Do not use it for production.
|
||||
|
|
Loading…
Reference in New Issue