Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/actions/cache-target-outputs/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Save cache for specific nx target outputs

name: Save cache
description: Save cache for all affected projects

inputs:
configuration:
description: The configuration to use (development | insiders | production)
required: true
default: development

target:
description: The target to use (build | test)
required: true
default: build

os:
description: The operating system of the runner
required: true
default: ${{ runner.os }}

runs:
using: 'node16'
main: 'index.js'
65 changes: 65 additions & 0 deletions .github/actions/cache-target-outputs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const cache = require('@actions/cache');
const core = require('@actions/core');
const { readFileSync, existsSync } = require('fs');
const { resolve } = require('path');
const { nxAffected } = import('../../../packages/tools/utils/nx-affected');

/**
* @param {string} project
* @returns {Promise<{
* targets?: { [key: string]: {
* outputs?: string[]
* } }
* }>}
*/
async function getProjectNxConfig(project) {
const packageJSONPath = resolve(__dirname, `../../../packages/${project}/package.json`);
const projectJSONPath = resolve(__dirname, `../../../packages/${project}/project.json`);

if (!existsSync(packageJSONPath) && !existsSync(projectJSONPath)) {
throw new Error(`Project config not found. One of the following should exist:\n ${packageJSONPath}\n ${projectJSONPath}\n`)
}

if (existsSync(packageJSONPath)) {
return JSON.parse(readFileSync(packageJSONPath)).nx;
} else {
return JSON.parse(readFileSync(projectJSONPath));
}
}

function parsePath(path, project) {
const projectRoot = resolve(__dirname, `../../../packages/${project}/`);
const workspaceRoot = resolve(__dirname, '../../');

path = path.replace('{projectRoot}', projectRoot);
path = path.replace('{workspaceRoot}', workspaceRoot);

return path;
}

async function run() {
const configuration = core.getInput('configuration');
const target = core.getInput('target');
const os = core.getInput('os');

const affected = await nxAffected(target);

for (const project of affected.projects) {
const key = `${os}-${configuration}-${target}-${project}`;
const nxConfig = await getProjectNxConfig(project);
const paths = (nxConfig.targets?.[target]?.outputs || []).map((path) => {
return parsePath(path, project);
});

if (paths.length) {
await cache.saveCache(paths, key);

console.log('Successfully cached paths:');
console.log(paths.join('\n'));
} else {
console.log('No outputs to cache');
}
}
}

run();
24 changes: 24 additions & 0 deletions .github/actions/restore-target-outputs/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Restore cache for specific nx target outputs

name: Restore cache
description: Restore cache for all projects

inputs:
configuration:
description: The configuration to use (development | insiders | production)
required: true
default: development

target:
description: The target to use (build | test)
required: true
default: build

os:
description: The operating system of the runner
required: true
default: ${{ runner.os }}

runs:
using: 'node16'
main: 'index.js'
65 changes: 65 additions & 0 deletions .github/actions/restore-target-outputs/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const cache = require('@actions/cache');
const core = require('@actions/core');
const { readFileSync, existsSync } = require('fs');
const { resolve } = require('path');
const { nxAffected } = import('../../../packages/tools/utils/nx-affected');

/**
* @param {string} project
* @returns {Promise<{
* targets?: { [key: string]: {
* outputs?: string[]
* } }
* }>}
*/
async function getProjectNxConfig(project) {
const packageJSONPath = resolve(__dirname, `../../../packages/${project}/package.json`);
const projectJSONPath = resolve(__dirname, `../../../packages/${project}/project.json`);

if (!existsSync(packageJSONPath) && !existsSync(projectJSONPath)) {
throw new Error(`Project config not found. One of the following should exist:\n ${packageJSONPath}\n ${projectJSONPath}\n`)
}

if (existsSync(packageJSONPath)) {
return JSON.parse(readFileSync(packageJSONPath)).nx;
} else {
return JSON.parse(readFileSync(projectJSONPath));
}
}

function parsePath(path, project) {
const projectRoot = resolve(__dirname, `../../../packages/${project}/`);
const workspaceRoot = resolve(__dirname, '../../');

path = path.replace('{projectRoot}', projectRoot);
path = path.replace('{workspaceRoot}', workspaceRoot);

return path;
}

async function run() {
const configuration = core.getInput('configuration');
const target = core.getInput('target');
const os = core.getInput('os');

const affected = await nxAffected(target);

for (const project of affected.projects) {
const key = `${os}-${configuration}-${target}-${project}`;
const nxConfig = await getProjectNxConfig(project);
const paths = (nxConfig.targets?.[target]?.outputs || []).map((path) => {
return parsePath(path, project);
});

if (paths.length) {
await cache.restoreCache(paths, key);

console.log('Successfully cached paths:');
console.log(paths.join('\n'));
} else {
console.log('No outputs to cache');
}
}
}

run();
37 changes: 37 additions & 0 deletions .github/workflows/_publish-code-coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Code Coverage

on:
workflow_call:
secrets:
CODECOV_TOKEN:
required: true
description: codecov token for authorization

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '16.x'

- name: Restore cache for target test
uses: ./.github/actions/restore-target-outputs
with:
target: test
configuration: development

- name: List all test files
id: list_lcov_files
run: echo "LCOV_FILES=$(node packages/tools/list-lcov-files.js)" >> $GITHUB_OUTPUT

- name: Upload app coverage to Codecov
uses: codecov/codecov-action@v2
with:
files: ${{ steps.list_lcov_files.outputs.LCOV_FILES }}
token: ${{ secrets.CODECOV_TOKEN }}
7 changes: 6 additions & 1 deletion .github/workflows/_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ jobs:
spring-application-properties: ${{ secrets.SPRING_APPLICATION_PROPERTIES }}
vernite-2022-private-key-pem: ${{ secrets.VERNITE_2022_PRIVATE_KEY_PEM }}

# Test by nx
- name: Test
run: yarn nx affected --target=test

- name: Cache results of affected projects
uses: ./.github/actions/cache-target-outputs
with:
target: test
configuration: ${{ inputs.configuration }}
7 changes: 6 additions & 1 deletion .github/workflows/dev-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
configuration: insiders

sonar_server:
needs: [build]
needs: [build, test]
uses: ./.github/workflows/_server-sonar.yml
secrets: inherit
with:
Expand All @@ -47,3 +47,8 @@ jobs:
secrets: inherit
with:
configuration: insiders

publish_code_coverage:
needs: [build, test]
uses: ./.github/workflows/_publish-code-coverage.yml
secrets: inherit
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@

Before starting make sure you have installed the supported version of node and yarn.

- yarn: `1.22.18`
- node: `16.13.0`
- java: `17`
- yarn: `1.22.18`
- java: `17.0.6`
- mvn: `3.9.1`

This repository is using nx workspace. To install all dependencies run:

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"private": true,
"prettier": "./.config/.prettierrc.js",
"dependencies": {
"@actions/cache": "^3.1.4",
"@angular/animations": "^14.2.12",
"@angular/cdk": "^14.2.7",
"@angular/cdk-experimental": "14.2.7",
Expand Down Expand Up @@ -129,4 +130,4 @@
"packages/*"
]
}
}
}
26 changes: 25 additions & 1 deletion packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,32 @@
"nx": {
"targets": {
"build": {
"inputs": [
"{workspaceRoot}/tsconfig.json",
"{projectRoot}/src/",
"{projectRoot}/angular.json",
"{projectRoot}/package.json",
"{projectRoot}/tailwind.config.js",
"{projectRoot}/tsconfig.app.json",
"{projectRoot}/tsconfig.json"
],
"outputs": [
"dist/"
"{projectRoot}/dist/"
]
},
"test": {
"inputs": [
"{workspaceRoot}/tsconfig.json",
"{projectRoot}/src/",
"{projectRoot}/angular.json",
"{projectRoot}/karma.conf.js",
"{projectRoot}/package.json",
"{projectRoot}/tailwind.config.js",
"{projectRoot}/tsconfig.json",
"{projectRoot}/tsconfig.spec.json"
],
"outputs": [
"{projectRoot}/coverage/"
]
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/client/tools/badge-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function requireIfExists(...modules) {
// pass and try next file
}
}
throw ('None of the provided modules exist.')
throw new Error('None of the provided modules exist.')
}

let { makeBadge } = require('badge-maker');
Expand Down
34 changes: 34 additions & 0 deletions packages/tools/list-lcov-files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { readdir } from 'fs/promises';
import { lstatSync } from 'fs';
import path from 'path';

const findFiles = async (dir, fileName, options) => {
dir = path.resolve(process.cwd(), dir);

const directoriesToOmit = options?.omit || [];
let matchedFiles = [];

const files = await readdir(dir);

for (const file of files) {
const pathToFile = path.resolve(dir, file);

if (directoriesToOmit.includes(file)) continue;

if (lstatSync(pathToFile).isDirectory()) {
matchedFiles = [].concat(matchedFiles, await findFiles(pathToFile, fileName, options))
} else {
if (file == fileName) {
matchedFiles.push(pathToFile);
}
}
}

return matchedFiles;
};

const files = await findFiles('.', 'lcov.info', {
omit: ['node_modules', 'maven_repository']
});

console.log(JSON.stringify(files))
25 changes: 25 additions & 0 deletions packages/tools/utils/nx-affected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { exec } from 'child_process';

/**
* @param {*} target
* @returns {Promise<{ projects: string[] }>}
*/
export function nxAffected(target) {
let command = `nx print-affected`;

if (target) {
command += ` --target=${target}`;
}

return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
if (error) {
reject(error);
}
if (stderr) {
reject(stderr);
}
resolve(stdout);
});
});
}
Loading