Skip to content

Commit

Permalink
💚 Add workflow for Continuous Integration (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
toridoriv committed Oct 23, 2023
1 parent 1d73a15 commit fd591f3
Show file tree
Hide file tree
Showing 10 changed files with 847 additions and 111 deletions.
68 changes: 68 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: ♾️ Continuous Integration

on: [push, pull_request]

env:
DENO_DIR: deno
DENO_DEPLOY_TOKEN: ${{ secrets.DENO_DEPLOY_TOKEN }}
ENVIRONMENT: ${{ vars.ENVIRONMENT }}
ADMIN_EMAILS: ${{ secrets.ADMIN_EMAILS }}
ADMIN_PASSWORDS: ${{ secrets.ADMIN_PASSWORDS }}

jobs:
check-code-quality:
name: ✅ Check Code Quality
runs-on: ubuntu-latest
steps:
- name: 👯‍♂️ Clone Repository
uses: actions/checkout@v4
- name: 🦕 Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: vx.x.x
- name: 🗄️ Start Database
uses: MongoCamp/mongodb-github-action@1.2.0
- name: 🔎 Lint Files
run: deno lint
- name: 🧪 Run Tests
run: deno test --allow-all

release-preview:
name: 🛰️ Release Preview
needs: check-code-quality
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: 👯‍♂️ Clone Repository
uses: actions/checkout@v4
- name: 🦕 Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: vx.x.x
- name: 🧰 Install Deploy Tool
run: deno install -A --no-check -r -f https://deno.land/x/deploy/deployctl.ts
- name: 🔥 Deploy
run: deno task deploy

release-production:
name: 🚀 Release Production
needs: check-code-quality
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: 👯‍♂️ Clone Repository
uses: actions/checkout@v4
- name: 🦕 Setup Deno
uses: denoland/setup-deno@v1
with:
deno-version: vx.x.x
- name: 🧰 Install Deploy Tool
run: deno install -A --no-check -r -f https://deno.land/x/deploy/deployctl.ts
- name: 🔥 Deploy
run: deno task deploy:prod
28 changes: 0 additions & 28 deletions .github/workflows/deploy-server.yml

This file was deleted.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Duofiction

**Duofiction** is a personal project made in my spare time for learning purposes.
**Duofiction** is a personal project made in my spare time for learning purposes.
69 changes: 68 additions & 1 deletion bin/commands/_utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Logger } from "@modules/logger/mod.ts";
import { CliffyCommand, WalkOptions, walkSync } from "../deps.ts";
import { CliffyCommand, existsSync, WalkOptions, walkSync } from "@bin/deps.ts";

export const logger = Logger.create({
severity: "DEBUG",
Expand Down Expand Up @@ -39,3 +39,70 @@ export async function registerCommands(

return commands;
}

export function getDependencyFilePaths(isDevelopment: boolean) {
const match: RegExp[] = [
/deps\./,
/modules\/.*\.d\.ts/,
];
const skip: RegExp[] = [/node_modules/, /deno\/npm\/registry/];

if (isDevelopment) {
match.push(/prettier\.config/, /scripts\.config/);
} else {
skip.push(/bin\//);
}

const options: WalkOptions = {
includeDirs: false,
exts: [".ts"],
match,
skip,
};

return [...walkSync("./", options)].map((e) => e.path);
}

export function runDenoCache(writeLock: boolean, path: string) {
logger.info(`ℹ️ Caching dependencies for ./${path}`);
const args = ["cache"];

if (writeLock) {
args.push("--lock=deno.lock");
}

args.push(path);

const output = executeCommand("deno", {
args,
});

return output;
}

export function removePreviousCache() {
const denoDir = getDenoDirPath();
const nodeModulesDir = "./node_modules";

if (existsSync(denoDir)) {
logger.info(`ℹ️ Deleting cache on ${denoDir}`);
executeCommand("rm", { args: ["-rf", denoDir] });
}

if (existsSync(nodeModulesDir)) {
logger.info(`ℹ️ Deleting cache on ${nodeModulesDir}`);
executeCommand("rm", { args: ["-rf", nodeModulesDir] });
}
}

export function getDenoDirPath() {
const output = executeCommand("deno", { args: ["info", "--json"] });

return JSON.parse(output).denoDir as string;
}

export function removeOldLockFile() {
logger.info(`ℹ️ Deleting deno.lock file...`);

executeCommand("rm", { args: ["./deno.lock"] });
}
93 changes: 22 additions & 71 deletions bin/commands/cache.ts
Original file line number Diff line number Diff line change
@@ -1,87 +1,38 @@
import { CliffyCommand } from "@bin/deps.ts";
import {
CliffyCommand,
existsSync,
type WalkOptions,
walkSync,
} from "../deps.ts";
import { executeCommand } from "./_utils.ts";
getDependencyFilePaths,
logger,
removePreviousCache,
runDenoCache,
} from "@bin/commands/_utils.ts";

const CacheCommand = new CliffyCommand.Command()
.name("cache")
.description("Cache all dependencies for this project.")
.option("-d, --development [development:boolean]", "", { default: false })
.option(
"-d, --development [development:boolean]",
"Include development dependencies.",
{ default: false },
)
.option(
"-c --clean [clean:boolean]",
"Use this option to remove all previous cache.",
{ default: false },
)
.action(function main(options) {
const paths = getDependencyFiles(options.development);
const paths = getDependencyFilePaths(options.development);

removePreviousCache();
if (options.clean) {
removePreviousCache();
}

paths.forEach(cacheDependencies);
paths.forEach(runDenoCache.bind(null, options.development));

console.info("✅ All dependencies were cached.");
logger.info("✅ All dependencies were cached.");
});

if (import.meta.main) {
CacheCommand.parse(Deno.args);
}

export default CacheCommand;

function getDependencyFiles(isDevelopment: boolean) {
const paths = [] as string[];
const skip = [/node_modules/, new RegExp("mod.ts")];
const opts: WalkOptions = {
includeDirs: false,
exts: [".ts"],
match: [
/deps\./,
new RegExp(".d.ts"),
],
skip,
};

if (!isDevelopment) {
skip.push(/bin\//);
} else {
opts.exts?.push(".mjs");
opts.match?.push(
new RegExp("prettier.config.mjs"),
new RegExp("scripts.config.ts"),
);
}

for (const entry of walkSync("./", opts)) {
paths.push(entry.path);
}

return paths;
}

function removePreviousCache() {
const denoDir = getCacheFile();
const nodeModulesDir = "./node_modules";

if (existsSync(denoDir)) {
console.info(`ℹ️ Deleting cache on ${denoDir}`);
executeCommand("rm", { args: ["-rf", denoDir] });
}

if (existsSync(nodeModulesDir)) {
console.info(`ℹ️ Deleting cache on ${nodeModulesDir}`);
executeCommand("rm", { args: ["-rf", nodeModulesDir] });
}
}

function cacheDependencies(path: string) {
console.info(`ℹ️ Caching dependencies for ./${path}`);
const output = executeCommand("deno", {
args: ["cache", "--lock-write", path],
});

return output;
}

function getCacheFile() {
const output = executeCommand("deno", { args: ["info", "--json"] });

return JSON.parse(output).denoDir as string;
}
34 changes: 34 additions & 0 deletions bin/commands/generate/lock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { CliffyCommand } from "@bin/deps.ts";
import {
getDependencyFilePaths,
removeOldLockFile,
removePreviousCache,
runDenoCache,
} from "@bin/commands/_utils.ts";

const LockCommand = new CliffyCommand.Command()
.name("lock")
.description("Generate the dependencies lock file.")
.option(
"-c --clean [clean:boolean]",
"Use this option to remove all previous cache.",
{ default: false },
)
.action(function main(options) {
removeOldLockFile();
const paths = getDependencyFilePaths(false);

if (options.clean) {
removePreviousCache();
}

paths.forEach(runDenoCache.bind(null, true));

console.info("✅ Lock file written!");
});

if (import.meta.main) {
LockCommand.parse(Deno.args);
}

export default LockCommand;
4 changes: 3 additions & 1 deletion deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@
},
"tasks": {
"cache": "deno task manage cache -d",
"cache:clean": "deno task manage cache -d -c",
"cache:prod": "deno task manage cache",
"deploy": "deployctl deploy --project=duofiction --exclude=node_modules,.env,.tmp,bin,.github,prettier-config.mjs,scripts.config.ts main.ts",
"deploy": "deployctl deploy --project=duofiction --exclude=.git,node_modules,.env,.tmp,bin,.github,prettier-config.mjs,scripts.config.ts duofiction.main.ts",
"deploy:prod": "deployctl deploy --prod --project=duofiction --exclude=.git,node_modules,.env,.tmp,bin,.github,prettier-config.mjs,scripts.config.ts duofiction.main.ts",
"generate:manifest": "deno task manage generate manifest --dir=routes --file=duofiction.manifest.ts",
"manage": "deno run --allow-all bin/manage.ts",
"start": "deno task generate:manifest && denon start"
Expand Down
Loading

0 comments on commit fd591f3

Please sign in to comment.