Skip to content

Commit

Permalink
feat: add automated synchronizer
Browse files Browse the repository at this point in the history
  • Loading branch information
eneajaho committed Dec 20, 2023
1 parent 5337384 commit fbe0384
Show file tree
Hide file tree
Showing 19 changed files with 8,336 additions and 2,744 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ testem.log
# System files
.DS_Store
Thumbs.db

.nx
18 changes: 18 additions & 0 deletions libs-scrapper-app/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": ["../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}
11 changes: 11 additions & 0 deletions libs-scrapper-app/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: 'libs-scrapper-app',
preset: '../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../coverage/libs-scrapper-app',
};
71 changes: 71 additions & 0 deletions libs-scrapper-app/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"name": "libs-scrapper-app",
"$schema": "../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs-scrapper-app/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@nx/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"platform": "node",
"outputPath": "dist/libs-scrapper-app",
"format": ["cjs"],
"bundle": false,
"main": "libs-scrapper-app/src/main.ts",
"tsConfig": "libs-scrapper-app/tsconfig.app.json",
"assets": ["src/assets/library-support-data.json"],
"generatePackageJson": true,
"esbuildOptions": {
"sourcemap": true,
"outExtension": {
".js": ".js"
}
}
},
"configurations": {
"development": {},
"production": {
"esbuildOptions": {
"sourcemap": false,
"outExtension": {
".js": ".js"
}
}
}
}
},
"extract": {
"command": "node ./dist/libs-scrapper-app/main.js",
"dependsOn": ["build"]
},
"serve": {
"executor": "@nx/js:node",
"defaultConfiguration": "development",
"options": {
"buildTarget": "libs-scrapper-app:build"
},
"configurations": {
"development": {
"buildTarget": "libs-scrapper-app:build:development"
},
"production": {
"buildTarget": "libs-scrapper-app:build:production"
}
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"]
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs-scrapper-app/jest.config.ts"
}
}
},
"tags": []
}
188 changes: 188 additions & 0 deletions libs-scrapper-app/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import { ANGULAR_VERSIONS, LibrarySupport } from '@libs/models';
import fs from 'fs';
import { Octokit } from 'octokit';

const supportData = () =>
JSON.parse(
fs.readFileSync(
'./src/assets/library-support-data.json'
) as unknown as string
);

const LIBRARY_SUPPORT_DATA: LibrarySupport[] = supportData();

// Replace 'GITHUB_TOKEN' with your GitHub personal access token
const octokit = new Octokit({
auth: process.env?.['GITHUB_TOKEN'] || '',
});

const GENERATE_RELEASES_JSON = process.env?.['GENERATE_RELEASES_JSON'];

// Function to fetch releases for a given repository
async function getReleases(repo: string): Promise<GithubRelease[]> {
try {
const { data } = await octokit.rest.repos.listReleases({
owner: repo.split('/')[0],
repo: repo.split('/')[1],
});

return data.map((release) => ({
link: release.html_url,
name: release.name,
tag: release.tag_name,
body: release.body,
}));
} catch (error: any) {
console.error(`Error fetching releases for ${repo}: ${error.message}`);
return [];
}
}

// Main function to fetch releases for all repositories
async function fetchAllReleases() {
const allReleases: Record<string, GithubRelease[]> = {};

// List of repositories to fetch releases
const repositories = getAllLibsThatHaveGithubReleases(LIBRARY_SUPPORT_DATA);

for (const repo of repositories) {
const releases = await getReleases(repo);
allReleases[repo] = releases;
}

return allReleases;
}

// Save releases to a JSON file
async function saveReleasesToFile(data: any, path: string) {
const jsonReleases = JSON.stringify(data, null, 2);

fs.writeFile(path, jsonReleases, 'utf8', (err) => {
if (err) {
console.error('Error writing to file:', err);
} else {
console.log('Releases saved to ' + path);
}
});
}

// Run the script
async function run() {
const releases = await fetchAllReleases();
const newLibrarySupportData = LIBRARY_SUPPORT_DATA;

// merge releases with library support data
for (const lib of newLibrarySupportData) {
const repo = lib.repo || getRepoFromUrl(lib.githubUrl);
const releasesForRepo = releases[repo];
lib.automated = releasesForRepo.length > 0;

for (const release of releasesForRepo) {
for (const angularVersion of ANGULAR_VERSIONS) {
const { support } = lib.versionSupport[angularVersion] || {};

if (support === undefined && angularVersion < 10) {
continue; // skip angular versions below 10 if the library doesn't have support for them
}

// if the library already has support for this version, skip
if (support === true) continue; // already has support for this version

if (support === 'partial' || support === 'progress') {
// already has partial support for this version check if this release has support for this version
if (releaseHasSupportForAngular(release, angularVersion + '')) {
lib.versionSupport[angularVersion] = {
libraryVersion: release.tag,
support: true,
link: release.link,
};
}
continue;
}

// check if the release has support for this angular version
if (releaseHasSupportForAngular(release, angularVersion + '')) {
lib.versionSupport[angularVersion] = {
libraryVersion: release.tag,
support: true,
link: release.link,
};
} else {
lib.versionSupport[angularVersion] = {
// if version is 15 or higher, set partial support to true because it probably works
support: angularVersion > 15 ? 'partial' : false,
};
}
}
}
}

if (GENERATE_RELEASES_JSON) {
await saveReleasesToFile(releases, 'releases.json');
}

await saveReleasesToFile(
newLibrarySupportData,
'src/assets/library-support-data.json'
);
}

run();

function libHasReleasesLinks(lib: LibrarySupport) {
for (const versionSupport of Object.values(lib.versionSupport)) {
if (
versionSupport.link?.includes('github.com') &&
versionSupport.link?.includes('releases')
) {
return true;
}
}
return false;
}

function getAllLibsThatHaveGithubReleases(
librarySupportData: LibrarySupport[]
) {
const libs = librarySupportData
.filter((lib) => {
// check if versionSupport items have a link that points to github releases
return libHasReleasesLinks(lib) || lib.githubUrl;
})
.map((lib) => {
if (lib.repo) return lib.repo;
return getRepoFromUrl(lib.githubUrl);
});
return libs;
}

function getRepoFromUrl(url: string) {
// return only the owner/repo part of the url
return url
.replace('https://github.com/', '')
.split('/') // split by slash
.slice(0, 2) // take only the first two parts
.join('/'); // join back with slash
}

function releaseHasSupportForAngular(
release: GithubRelease,
angularVersion: string
) {
const body = release.body || '';
// check if the release body contains the angular version
return (
body.includes('a `' + angularVersion) || // ngular `8*** or ngular `9*** or ngular `10*** etc. (ng-bootstrap)
body.includes('v ' + angularVersion) ||
body.includes('a' + angularVersion) || // a16 or a17 etc. (ng-mocks)
body.includes('ngular ' + angularVersion) || // remove the 'a' from 'angular' to match both 'angular' and 'Angular'
body.includes('ngular v' + angularVersion) // (ngx-translate/core)
);
}

interface GithubRelease {
name: string | null;
tag: string;
body: string | null | undefined;
link: string;
}
10 changes: 10 additions & 0 deletions libs-scrapper-app/tsconfig.app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../dist/out-tsc",
"module": "CommonJS",
"types": ["node"]
},
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
"include": ["src/**/*.ts"]
}
16 changes: 16 additions & 0 deletions libs-scrapper-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"extends": "../tsconfig.json",
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.app.json"
},
{
"path": "./tsconfig.spec.json"
}
],
"compilerOptions": {
"esModuleInterop": true
}
}
14 changes: 14 additions & 0 deletions libs-scrapper-app/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"jest.config.ts",
"src/**/*.test.ts",
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
4 changes: 4 additions & 0 deletions libs/models/src/lib-support.interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export const ANGULAR_VERSIONS = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8];

export interface LibrarySupport {
name: string; // name of the library (e.g. @rx-angular/isr)
npmUrl: string; // url to the npm library
githubUrl: string; // url to the github repo
repo?: string; // name of the github repo (e.g. rx-angular/rx-angular)
automated?: boolean; // if the library is automated

versionSupport: {
// key is version of angular (e.g. 11.0.0)
Expand Down
Loading

0 comments on commit fbe0384

Please sign in to comment.