All files / libs/tools/plugin/src/executors/gitlab-badge-updater executor.ts

0% Statements 0/67
0% Branches 0/1
0% Functions 0/1
0% Lines 0/67

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68                                                                                                                                       
import { type ProjectBadgeSchema } from '@gitbeaker/core';
import { type Executor } from '@nx/devkit';

import { assert, isEnum } from '@amalia/ext/typescript';
import { getAllProjectBadges, makeGitlabClient } from '@amalia/vendors/gitlab';

import { debug } from './debug';
import { getPackageJsonVersions, PackageNames } from './getPackageJsonVersions';
import { type GitLabBadgeUpdaterExecutorSchema } from './types';

// Base URL for each package to get Color, Logo and main label
const URL_ENUM: Record<PackageNames, string> = {
  [PackageNames.NODE]: 'https://img.shields.io/static/v1?label=Node.js&color=%23339933&logo=node.js',
  [PackageNames.YARN]: 'https://img.shields.io/static/v1?label=Yarn&color=%232C8EBB&logo=yarn',
  [PackageNames.NX]: 'https://img.shields.io/static/v1?label=Nx&color=%23143055&logo=nx',
  [PackageNames.NEST]: 'https://img.shields.io/static/v1?label=NestJS&color=%23E0234E&logo=nestJs',
  [PackageNames.REACT]: 'https://img.shields.io/static/v1?label=React&color=%2361DAFB&logo=react',
};

export const executor: Executor<GitLabBadgeUpdaterExecutorSchema> = async (
  { token = '', projectId = '' },
  { isVerbose = false },
) => {
  debug.enabled ||= isVerbose;

  assert(token, 'token is required');

  const packages = getPackageJsonVersions();

  const gitlabClient = makeGitlabClient({
    token,
    camelize: false,
  });

  const badges: ProjectBadgeSchema[] = await getAllProjectBadges(gitlabClient, { projectId });

  assert(badges.length, `No badges found for project ${projectId}`);

  debug('Found %d badges for project %s', badges.length, projectId);

  await Promise.all(
    Object.entries(packages).map(async ([key, version]): Promise<void> => {
      const badge = badges.find((badge) => badge.name.includes(key));
      const badgeVersion = badge?.image_url.split('message=')[1];

      if (!badge || badgeVersion === version) {
        // if there was no corresponding badge or the version is the same, skip
        debug('Skipping %s badge', key);
        return;
      }

      assert(isEnum(key, PackageNames), `Invalid package name: ${key}`);

      debug(`Updating ${key} badge to version ${version}`);
      const url = `${URL_ENUM[key]}&message=${version}`;
      await gitlabClient.ProjectBadges.edit(projectId, badge.id, {
        imageUrl: url,
      });
    }),
  );

  return {
    success: true,
  };
};

export default executor;