diff --git a/.github/scripts/_meta.mts b/.github/scripts/_meta.mts index 1847621d..e9d5b00f 100644 --- a/.github/scripts/_meta.mts +++ b/.github/scripts/_meta.mts @@ -4,10 +4,17 @@ import fs from "node:fs"; export type VerticalType = "app" | "lib" | "pkg"; +export type ImageInfo = { + readonly name: string; +}; + export type Vertical = { readonly type: VerticalType; readonly name: string; + readonly shortName: string; readonly path: string; + readonly relPath: string; + readonly image?: ImageInfo; readonly rawConfig: Readonly>; }; @@ -17,6 +24,8 @@ const vertialDirs = { pkg: "src/pkgs", }; +const last = (arr: string[]) => arr[arr.length - 1]; + const readVertical = (type: VerticalType, dirPath: string): Vertical => { const verticalPath = path.resolve(dirPath); const dirName = path.basename(verticalPath); @@ -33,7 +42,28 @@ const readVertical = (type: VerticalType, dirPath: string): Vertical => { name = config.name; } - return { type, name, path: verticalPath, rawConfig: config }; + let shortName = last(name.split(".")); + if (typeof config.shortName === "string" && config.shortName) { + shortName = config.shortName; + } + + let image: ImageInfo | undefined; + if ("image" in config) { + // TODO: validate? + image = { + name: (config.image as any).name, + }; + } + + return { + type, + name, + shortName, + path: verticalPath, + relPath: dirPath, + image, + rawConfig: config, + }; }; const apps = await globby(`${vertialDirs.app}/*`, { onlyDirectories: true }); diff --git a/.github/scripts/bootstrap-db.mts b/.github/scripts/bootstrap-db.mts new file mode 100644 index 00000000..021f7463 --- /dev/null +++ b/.github/scripts/bootstrap-db.mts @@ -0,0 +1,109 @@ +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; + +const argv = yargs(hideBin(process.argv)) + .option("deploy-api", { + description: "Deploy API base path", + }) + .option("subscription-id", { + type: "string", + required: true, + }) + .option("resource-group", { + type: "string", + required: true, + }) + .option("server-name", { + type: "string", + required: true, + }) + .option("key-vault-name", { + type: "string", + required: true, + }) + .option("user", { + type: "string", + required: true, + }) + .option("database", { + type: "string", + required: true, + }) + .option("role-prefix", { + type: "string", + required: true, + }) + .option("schema", { + type: "array", + required: true, + }) + .parse(); + +const request = { + resources: { + subscriptionId: argv.subscriptionId, + resourceGroup: argv.resourceGroup, + serverName: argv.serverName, + keyVaultName: argv.keyVaultName, + user: argv.user, + }, + databaseName: argv.database, + userPrefix: argv.rolePrefix, + schemas: Object.fromEntries(argv.schema.map((n) => [n, {}])), +}; + +// console.log(request); +// process.exit(1); + +const baseUrl = new URL(argv.deployApi); +if (baseUrl.protocol === "http:") { + baseUrl.protocol = "ws:"; +} else if (baseUrl.protocol === "https:") { + baseUrl.protocol = "wss:"; +} else { + throw new Error(`Unsupported protocol: ${baseUrl.protocol}`); +} + +const ws = new WebSocket( + new URL("api/v1/database/bootstrap", baseUrl), + "altinn.task-pipeline" +); + +let pending = Promise.resolve(); + +const write = (data: Blob) => { + const buffer = data.arrayBuffer(); + pending = pending + .then(() => buffer) + .then((buffer) => { + var arr = new Uint8Array(buffer); + process.stderr.write(arr); + }) + .catch((err) => { + console.error(err); + process.exit(1); + }); +}; + +ws.addEventListener("open", (e) => { + ws.send(JSON.stringify(request)); +}); + +ws.addEventListener("message", (ev) => { + write(ev.data); +}); + +ws.addEventListener("close", (ev) => { + console.log("closed", ev.code, ev.reason); + ws.close(); + + if (ev.code !== 4000) { + process.exit(1); + } +}); + +ws.addEventListener("error", (ev) => { + if (ev && "message" in ev) { + console.error("error", ev.message); + } +}); diff --git a/.github/scripts/list-verticals.mts b/.github/scripts/list-verticals.mts new file mode 100644 index 00000000..8ce0ef15 --- /dev/null +++ b/.github/scripts/list-verticals.mts @@ -0,0 +1,38 @@ +import { verticals } from "./_meta.mts"; +import * as actions from "@actions/core"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; + +const argv = yargs(hideBin(process.argv)) + .option("type", { + type: "array", + required: true, + }) + .parse(); + +let output = verticals; +if (argv.type) { + output = verticals.filter((v) => argv.type.includes(v.type)); +} + +const paths = output.map((v) => v.relPath); +var matrix = { + shortName: output.map((v) => v.shortName), + include: output.map((v) => { + const ret: Record = { + path: v.relPath, + name: v.name, + shortName: v.shortName, + type: v.type, + }; + + if (v.image && v.image.name) { + ret.imageName = v.image.name; + } + + return ret; + }), +}; + +actions.setOutput("matrix", JSON.stringify(matrix)); +actions.setOutput("verticals", JSON.stringify(paths)); diff --git a/.github/scripts/package.json b/.github/scripts/package.json index df1243f2..c05d0575 100644 --- a/.github/scripts/package.json +++ b/.github/scripts/package.json @@ -6,12 +6,14 @@ "author": "", "private": true, "devDependencies": { + "@actions/core": "^1.11.1", "@octokit/action": "^7.0.0", "@types/node": "^20.11.30", "chalk": "^5.3.0", "globby": "^14.0.1", "tsx": "^4.7.1", "typescript": "^5.4.3", + "yargs": "^17.7.2", "zx": "^8.0.0" } } diff --git a/.github/scripts/pnpm-lock.yaml b/.github/scripts/pnpm-lock.yaml index 7bc6a78a..e34c1173 100644 --- a/.github/scripts/pnpm-lock.yaml +++ b/.github/scripts/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: devDependencies: + '@actions/core': + specifier: ^1.11.1 + version: 1.11.1 '@octokit/action': specifier: ^7.0.0 version: 7.0.0 @@ -26,12 +29,27 @@ importers: typescript: specifier: ^5.4.3 version: 5.6.2 + yargs: + specifier: ^17.7.2 + version: 17.7.2 zx: specifier: ^8.0.0 version: 8.1.9 packages: + '@actions/core@1.11.1': + resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==} + + '@actions/exec@1.1.1': + resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==} + + '@actions/http-client@2.2.3': + resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==} + + '@actions/io@1.1.3': + resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==} + '@esbuild/aix-ppc64@0.23.1': resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} @@ -176,6 +194,10 @@ packages: cpu: [x64] os: [win32] + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -251,6 +273,14 @@ packages: '@types/node@20.16.11': resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + before-after-hook@3.0.2: resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} @@ -262,11 +292,29 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + esbuild@0.23.1: resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -283,6 +331,10 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} @@ -302,6 +354,10 @@ packages: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -329,6 +385,10 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -343,6 +403,14 @@ packages: resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} engines: {node: '>=14.16'} + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -352,6 +420,10 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + typescript@5.6.2: resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==} engines: {node: '>=14.17'} @@ -360,6 +432,10 @@ packages: undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + undici@6.19.8: resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==} engines: {node: '>=18.17'} @@ -371,6 +447,22 @@ packages: universal-user-agent@7.0.2: resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + zx@8.1.9: resolution: {integrity: sha512-UHuLHphHmsBYKkAchkSrEN4nzDyagafqC9HUxtc1J7eopaScW6H9dsLJ1lmkAntnLtDTGoM8fa+jrJrXiIfKFA==} engines: {node: '>= 12.17.0'} @@ -378,6 +470,22 @@ packages: snapshots: + '@actions/core@1.11.1': + dependencies: + '@actions/exec': 1.1.1 + '@actions/http-client': 2.2.3 + + '@actions/exec@1.1.1': + dependencies: + '@actions/io': 1.1.3 + + '@actions/http-client@2.2.3': + dependencies: + tunnel: 0.0.6 + undici: 5.28.4 + + '@actions/io@1.1.3': {} + '@esbuild/aix-ppc64@0.23.1': optional: true @@ -450,6 +558,8 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true + '@fastify/busboy@2.1.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -543,6 +653,12 @@ snapshots: dependencies: undici-types: 6.19.8 + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + before-after-hook@3.0.2: {} braces@3.0.3: @@ -551,6 +667,20 @@ snapshots: chalk@5.3.0: {} + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + emoji-regex@8.0.0: {} + esbuild@0.23.1: optionalDependencies: '@esbuild/aix-ppc64': 0.23.1 @@ -578,6 +708,8 @@ snapshots: '@esbuild/win32-ia32': 0.23.1 '@esbuild/win32-x64': 0.23.1 + escalade@3.2.0: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -597,6 +729,8 @@ snapshots: fsevents@2.3.3: optional: true + get-caller-file@2.0.5: {} + get-tsconfig@4.8.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -618,6 +752,8 @@ snapshots: is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -637,6 +773,8 @@ snapshots: queue-microtask@1.2.3: {} + require-directory@2.1.1: {} + resolve-pkg-maps@1.0.0: {} reusify@1.0.4: {} @@ -647,6 +785,16 @@ snapshots: slash@5.1.0: {} + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -658,16 +806,42 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tunnel@0.0.6: {} + typescript@5.6.2: {} undici-types@6.19.8: {} + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + undici@6.19.8: {} unicorn-magic@0.1.0: {} universal-user-agent@7.0.2: {} + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + zx@8.1.9: optionalDependencies: '@types/fs-extra': 11.0.4 diff --git a/.github/workflows/_deploy-app.yml b/.github/workflows/_deploy-app.yml new file mode 100644 index 00000000..8b231dcb --- /dev/null +++ b/.github/workflows/_deploy-app.yml @@ -0,0 +1,53 @@ +name: "Template: Deploy app" + +on: + workflow_call: + inputs: + repository: + description: Docker image repository (part of the registry) + type: string + default: altinn/altinn-authorization-tmp + + path: + required: true + description: Path to the app + type: string + + imageName: + required: true + description: Name of the image + type: string + +jobs: + build-push: + name: Build and Push + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + name: Checkout repository + + - name: Set Short SHA + run: | + short_sha=$(git rev-parse --short ${{ github.sha }}) + echo "short_sha=$short_sha" >> $GITHUB_ENV + + - uses: docker/login-action@v3 + name: Login to ghcr + with: + registry: ghrc.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - uses: docker/build-push-action@v6 + id: build + name: Build and Push + with: + file: ${{ inputs.path }}/Dockerfile + context: ./ + push: true + tags: ghrc.io/${{ inputs.repository }}/${{ inputs.imageName }}:${{ env.short_sha }} diff --git a/.github/workflows/_find-verticals.yml b/.github/workflows/_find-verticals.yml new file mode 100644 index 00000000..f3d47c46 --- /dev/null +++ b/.github/workflows/_find-verticals.yml @@ -0,0 +1,41 @@ +name: "Template: Find verticals" + +on: + workflow_call: + outputs: + matrix: + value: ${{ jobs.list.outputs.matrix }} + description: JSON object containing a job matrix of verticals + + verticals: + value: ${{ jobs.list.outputs.verticals }} + description: JSON list of folders in either + + inputs: + type: + required: true + description: + type: string + +jobs: + list: + name: Find ${{ inputs.type }}s + runs-on: ubuntu-latest + + outputs: + verticals: ${{ steps.list.outputs.verticals }} + matrix: ${{ steps.list.outputs.matrix }} + + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v3 + with: + version: 9 + run_install: | + - cwd: .github/scripts + args: [--frozen-lockfile] + - args: [--global, tsx] + + - name: Find all ${{ inputs.type }} + id: list + run: tsx ./.github/scripts/list-verticals.mts --type ${{ inputs.type }} diff --git a/.github/workflows/apps-cd.yml b/.github/workflows/apps-cd.yml deleted file mode 100644 index d43b1c1e..00000000 --- a/.github/workflows/apps-cd.yml +++ /dev/null @@ -1,107 +0,0 @@ -name: Apps CD - -on: - workflow_dispatch: - push: - branches: - - main - paths: - - src/** - - .github/workflows/apps-* - -env: - registry: ghcr.io - image_repository: altinn/altinn-authorization-tmp - dir: src/apps - python_ver: "3.12" - -jobs: - bundle: - name: Bundle - uses: ./.github/workflows/bundle-template.yml - with: - dir: apps - - build: - name: Build - needs: bundle - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - strategy: - matrix: - name: ${{ fromJson(needs.bundle.outputs.dirs) }} - steps: - - uses: actions/checkout@v4 - name: Checkout repository - - - name: Set Short SHA - run: | - short_sha=$(git rev-parse --short ${{ github.sha }}) - echo "short_sha=$short_sha" >> $GITHUB_ENV - - - uses: docker/login-action@v3 - name: Login to ${{ env.registry }} - with: - registry: ${{ env.registry }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Python Install - uses: actions/setup-python@v5 - with: - python-version: ${{ env.python_ver }} - - - name: Read Metadata - working-directory: .github/scripts - run: | - python metadata.py --file="../../${{ env.dir }}/${{ matrix.name }}/metadata.json" - - - uses: docker/build-push-action@v6 - id: build - name: Build and Push - with: - file: ${{ env.dir }}/${{ matrix.name }}/Dockerfile - context: ./ - push: true - tags: ${{ env.registry }}/${{ env.image_repository }}/${{ env.image_name }}:${{ env.short_sha }} - - - uses: cloudposse/github-action-matrix-outputs-write@v0 - id: out - with: - matrix-step-name: ${{ github.job }} - matrix-key: ${{ matrix.name }} - outputs: |- - image: ${{ env.registry }}/${{ env.image_repository }}/${{ env.image_name }}:${{ env.short_sha }} - - read: - name: Read Build Outputs - runs-on: ubuntu-latest - needs: [build] - outputs: - result: "${{ steps.read.outputs.result }}" - steps: - - name: Parse matrix result - uses: cloudposse/github-action-matrix-outputs-read@v0 - id: read - with: - matrix-step-name: build - - deploy: - name: Deploy - secrets: inherit - needs: - - read - - bundle - uses: ./.github/workflows/infra-cd-template.yml - strategy: - fail-fast: false - matrix: - name: ${{ fromJson(needs.bundle.outputs.dirs) }} - environment: [at21] - with: - working_dir: src/apps/${{ matrix.name }}/deploy - environment: ${{ matrix.environment }} - tf_state: ${{ matrix.name }}.tfstate - tf_args: -var image=${{ fromJson(needs.read.outputs.result).image[matrix.name] }} diff --git a/.github/workflows/bundle-template.yml b/.github/workflows/bundle-template.yml deleted file mode 100644 index d980dec3..00000000 --- a/.github/workflows/bundle-template.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: bundle-template.yml - -on: - workflow_call: - outputs: - dirs: - value: ${{ jobs.bundle.outputs.names }} - description: JSON list of folders in either - - inputs: - dir: - required: true - description: - type: string - -jobs: - bundle: - name: ${{ inputs.dir }} - runs-on: ubuntu-latest - outputs: - names: ${{ steps.list.outputs.result }} - steps: - - uses: actions/checkout@v4 - - name: List ${{ inputs.dir }} - id: list - working-directory: src/${{ inputs.dir }} - run: | - result=$(find . -maxdepth 1 -type d -not -path '.' -printf '%P\n' | jq -R -s -c 'split("\n")[:-1]') - echo "result=$result" >> $GITHUB_OUTPUT diff --git a/.github/workflows/cd-apps.yml b/.github/workflows/cd-apps.yml new file mode 100644 index 00000000..0263c4f8 --- /dev/null +++ b/.github/workflows/cd-apps.yml @@ -0,0 +1,30 @@ +name: "CD: Apps" + +on: + workflow_dispatch: + push: + branches: + - main + +env: + registry: ghcr.io + image_repository: altinn/altinn-authorization-tmp + +jobs: + find-verticals: + uses: ./.github/workflows/_find-verticals.yml + with: + type: app + + deploy: + name: Deploy + needs: find-verticals + + strategy: + matrix: ${{ fromJson(needs.find-verticals.outputs.matrix) }} + + uses: ./.github/workflows/_deploy-app.yml + with: + repository: altinn/altinn-authorization-tmp + path: ${{ matrix.path }} + imageName: ${{ matrix.imageName }} diff --git a/.github/workflows/apps-ci.yml b/.github/workflows/pr-apps.yml similarity index 58% rename from .github/workflows/apps-ci.yml rename to .github/workflows/pr-apps.yml index a827f2ef..788fd73c 100644 --- a/.github/workflows/apps-ci.yml +++ b/.github/workflows/pr-apps.yml @@ -1,9 +1,7 @@ -name: Apps CI +name: "PR: Apps" on: - push: - branches-ignore: - - main + pull_request: paths: - src/** - .github/workflows/apps-* @@ -11,22 +9,19 @@ on: env: DOTNET_VERSION: 8.0.x - DIR: src/apps jobs: - bundle: - name: Bundle Apps - uses: ./.github/workflows/bundle-template.yml + find-verticals: + uses: ./.github/workflows/_find-verticals.yml with: - dir: apps + type: app ci: name: CI runs-on: ubuntu-latest - needs: bundle + needs: find-verticals strategy: - matrix: - name: ${{ fromJson(needs.bundle.outputs.dirs) }} + matrix: ${{ fromJson(needs.find-verticals.outputs.matrix) }} steps: - uses: actions/checkout@v4 @@ -36,10 +31,10 @@ jobs: dotnet-version: ${{ env.DOTNET_VERSION }} - name: Build - working-directory: ${{ env.DIR }}/${{ matrix.name }} + working-directory: ${{ matrix.path }} run: dotnet build - name: Test if: always() - working-directory: src/apps/${{ matrix.name }} + working-directory: ${{ matrix.path }} run: dotnet test --no-build diff --git a/.github/workflows/pr-check-slns.yml b/.github/workflows/pr-check-slns.yml new file mode 100644 index 00000000..faec1f2a --- /dev/null +++ b/.github/workflows/pr-check-slns.yml @@ -0,0 +1,35 @@ +name: "PR: Check solution files" + +on: + pull_request: {} + +jobs: + check-slns: + name: Check sln files + if: ((github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false) || github.event_name == 'push') && github.repository_owner == 'Altinn' && github.actor != 'dependabot[bot]' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: | + 8.0.x + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - uses: pnpm/action-setup@v3 + with: + version: 9 + run_install: | + - cwd: .github/scripts + args: [--frozen-lockfile] + - args: [--global, tsx] + + - name: Update all sln files + run: tsx ./.github/scripts/update-sln-files.mts + + - name: Assert that no sln files have changed + run: git diff --exit-code diff --git a/.github/workflows/libs-ci.yml b/.github/workflows/pr-libs.yml similarity index 58% rename from .github/workflows/libs-ci.yml rename to .github/workflows/pr-libs.yml index 3f475017..1a1695a0 100644 --- a/.github/workflows/libs-ci.yml +++ b/.github/workflows/pr-libs.yml @@ -1,9 +1,7 @@ -name: Libs CI +name: "PR: Libs" on: - push: - branches-ignore: - - main + pull_request: paths: - src/** - .github/workflows/libs-* @@ -13,19 +11,17 @@ env: DIR: src/libs jobs: - bundle: - name: Bundle Libs - uses: ./.github/workflows/bundle-template.yml + find-verticals: + uses: ./.github/workflows/_find-verticals.yml with: - dir: libs + type: lib ci: name: CI runs-on: ubuntu-latest - needs: bundle + needs: find-verticals strategy: - matrix: - name: ${{ fromJson(needs.bundle.outputs.dirs) }} + matrix: ${{ fromJson(needs.find-verticals.outputs.matrix) }} steps: - uses: actions/checkout@v4 @@ -36,10 +32,10 @@ jobs: dotnet-version: ${{ env.DOTNET_VERSION }} - name: Build - working-directory: ${{ env.DIR }}/${{ matrix.name }} + working-directory: ${{ matrix.path }} run: dotnet build - name: Test if: always() - working-directory: ${{ env.DIR }}/${{ matrix.name }} + working-directory: ${{ matrix.path }} run: dotnet test --no-build diff --git a/src/apps/Altinn.Authorization.AccessPackages/Makefile b/src/apps/Altinn.Authorization.AccessPackages/Makefile deleted file mode 100644 index 76636fb3..00000000 --- a/src/apps/Altinn.Authorization.AccessPackages/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -APP=garfield -REGISTRY=acrshared004at21.azurecr.io -TAG=21 - -all: docker_build docker_push - -docker_build: - docker build \ - -t $(APP) \ - -f Dockerfile \ - ../../.. - -docker_push: - docker tag $(APP) $(REGISTRY)/$(APP):$(TAG) - docker push $(REGISTRY)/$(APP):$(TAG) \ No newline at end of file diff --git a/src/apps/Altinn.Authorization.AccessPackages/conf.json b/src/apps/Altinn.Authorization.AccessPackages/conf.json new file mode 100644 index 00000000..a70f025e --- /dev/null +++ b/src/apps/Altinn.Authorization.AccessPackages/conf.json @@ -0,0 +1,5 @@ +{ + "image": { + "name": "altinn-authorization-access-packages" + } +} diff --git a/src/apps/Altinn.Authorization.AccessPackages/metadata.json b/src/apps/Altinn.Authorization.AccessPackages/metadata.json deleted file mode 100644 index 47c6671f..00000000 --- a/src/apps/Altinn.Authorization.AccessPackages/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "image_name": "altinn-authorization-access-packages" -} \ No newline at end of file diff --git a/src/apps/Altinn.Authorization.DeployApi/conf.json b/src/apps/Altinn.Authorization.DeployApi/conf.json new file mode 100644 index 00000000..dde997dc --- /dev/null +++ b/src/apps/Altinn.Authorization.DeployApi/conf.json @@ -0,0 +1,5 @@ +{ + "image": { + "name": "altinn-authorization-deployapi" + } +} diff --git a/src/apps/Altinn.Authorization.DeployApi/metadata.json b/src/apps/Altinn.Authorization.DeployApi/metadata.json deleted file mode 100644 index e0ba3d09..00000000 --- a/src/apps/Altinn.Authorization.DeployApi/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "image_name": "altinn-authorization-deployapi" -} \ No newline at end of file diff --git a/src/apps/Altinn.Authorization.Index/Makefile b/src/apps/Altinn.Authorization.Index/Makefile deleted file mode 100644 index 76636fb3..00000000 --- a/src/apps/Altinn.Authorization.Index/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -APP=garfield -REGISTRY=acrshared004at21.azurecr.io -TAG=21 - -all: docker_build docker_push - -docker_build: - docker build \ - -t $(APP) \ - -f Dockerfile \ - ../../.. - -docker_push: - docker tag $(APP) $(REGISTRY)/$(APP):$(TAG) - docker push $(REGISTRY)/$(APP):$(TAG) \ No newline at end of file diff --git a/src/apps/Altinn.Authorization.Index/conf.json b/src/apps/Altinn.Authorization.Index/conf.json new file mode 100644 index 00000000..90caa092 --- /dev/null +++ b/src/apps/Altinn.Authorization.Index/conf.json @@ -0,0 +1,5 @@ +{ + "image": { + "name": "altinn-authorization-index" + } +} diff --git a/src/apps/Altinn.Authorization.Index/metadata.json b/src/apps/Altinn.Authorization.Index/metadata.json deleted file mode 100644 index 2ccbf2a5..00000000 --- a/src/apps/Altinn.Authorization.Index/metadata.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "image_name": "altinn-authorization-index" -} \ No newline at end of file