npmci/readme.md
2024-05-24 15:54:32 +02:00

13 KiB

@ship.zone/npmci

A tool to enhance Node.js and Docker workflows within GitLab CI, providing various CI/CD utilities.

Install

To install @ship.zone/npmci, you can use npm or yarn:

# Using npm
npm install @ship.zone/npmci

# Using yarn
yarn add @ship.zone/npmci

Usage

npmci is designed to streamline CI/CD processes, particularly in Docker and Node.js environments. The following sections illustrate its usage in various scenarios, from handling Node versions to building Docker images and more.

1. Integration with GitLab CI, GitHub CI, and Gitea CI

GitLab CI

An example of integrating npmci into a GitLab CI configuration could look like this:

image: hosttoday/ht-docker-node:npmci

stages:
  - prepare
  - build
  - test
  - deploy

default:
  before_script:
    - npmci node install stable
    - npmci npm install

prepare:
  stage: prepare
  script:
    - npmci prepare npm
    - npmci prepare docker

build:
  stage: build
  script:
    - npmci docker build

test:
  stage: test
  script:
    - npmci npm test

deploy:
  stage: deploy
  script:
    - npmci publish npm
    - npmci docker push

  environment:
    name: production
    url: http://example.com

GitHub Actions

Similarly, you can set up npmci in GitHub Actions:

name: CI Pipeline

on:
  push:
    branches:
      - main

jobs:
  prepare:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14'
      - run: npm install -g @ship.zone/npmci
      - run: npmci node install stable
      - run: npmci npm install

  build:
    runs-on: ubuntu-latest
    needs: prepare
    steps:
      - run: npmci docker build

  test:
    runs-on: ubuntu-latest
    needs: build
    steps:
      - run: npmci npm test

  deploy:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - run: npmci publish npm
      - run: npmci docker push

Gitea CI

Lastly, for Gitea CI:

image: hosttoday/ht-docker-node:npmci

pipelines:
  default:
    - step:
        name: Prepare
        image: hosttoday/ht-docker-node:npmci
        commands:
          - npmci node install stable
          - npmci npm install
          - npmci prepare npm
          - npmci prepare docker

    - step:
        name: Build
        image: hosttoday/ht-docker-node:npmci
        commands:
          - npmci docker build

    - step:
        name: Test
        image: hosttoday/ht-docker-node:npmci
        commands:
          - npmci npm test

    - step:
        name: Deploy
        image: hosttoday/ht-docker-node:npmci
        commands:
          - npmci publish npm
          - npmci docker push

2. Handle Node Versions

One of the core features of npmci is managing Node versions in your CI environment. You can specify which version of Node to install:

import { Npmci } from '@ship.zone/npmci';

async function manageNodeVersions() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.nodejsManager.handleCli({
    _: ['node', 'install', 'stable'] // Installs the latest stable version
  });

  await npmciInstance.nodejsManager.handleCli({
    _: ['node', 'install', 'lts'] // Installs the Long-Term Support (LTS) version
  });

  await npmciInstance.nodejsManager.handleCli({
    _: ['node', 'install', 'legacy'] // Installs a legacy version
  });

  await npmciInstance.nodejsManager.handleCli({
    _: ['node', 'install', '14.17.0'] // Install a specific version of Node
  });
}

manageNodeVersions().then(() => console.log('Node versions managed successfully.'));

3. Handling npm and Yarn Tasks

npmci provides numerous utilities to streamline npm and yarn workflow tasks within a CI/CD pipeline.

import { Npmci } from '@ship.zone/npmci';

async function manageNpmTasks() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.npmManager.handleCli({ _: ['npm', 'install'] }); // Installs dependencies
  await npmciInstance.npmManager.handleCli({ _: ['npm', 'test'] }); // Runs tests
  await npmciInstance.npmManager.handleCli({ _: ['npm', 'publish'] }); // Publishes the package
}

manageNpmTasks().then(() => console.log('Npm tasks handled successfully.'));

4. Docker Task Handling

npmci simplifies Docker operations, particularly in building, testing, and publishing Docker images.

Prepare Docker Environment:

import { Npmci } from '@ship.zone/npmci';

async function prepareDocker() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.dockerManager.handleCli({ _: ['docker', 'prepare'] }); // Prepares Docker environment
}

prepareDocker().then(() => console.log('Docker environment prepared successfully.'));

Building Docker Images:

import { Npmci } from '@ship.zone/npmci';

async function buildDockerImages() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.dockerManager.handleCli({ _: ['docker', 'build'] }); // Builds Docker images
}

buildDockerImages().then(() => console.log('Docker images built successfully.'));

Testing Docker Images:

import { Npmci } from '@ship.zone/npmci';

async function testDockerImages() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.dockerManager.handleCli({ _: ['docker', 'test'] }); // Tests Docker images
}

testDockerImages().then(() => console.log('Docker images tested successfully.'));

Publishing Docker Images:

import { Npmci } from '@ship.zone/npmci';

async function pushDockerImages() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.dockerManager.handleCli({ _: ['docker', 'push'] }); // Pushes Docker images to registry
}

pushDockerImages().then(() => console.log('Docker images pushed successfully.'));

5. Managing Docker Registries

npmci can handle multiple Docker registries and allows for easy integration within your CI pipeline.

Logging in to Docker Registries:

import { Npmci } from '@ship.zone/npmci';

async function loginToDockerRegistries() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.dockerManager.handleCli({ _: ['docker', 'login'] }); // Logs into all configured Docker registries
}

loginToDockerRegistries().then(() => console.log('Logged into Docker registries.'));

Pulling Docker Images:

import { Npmci } from '@ship.zone/npmci';

async function pullDockerImages() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.dockerManager.handleCli({ _: ['docker', 'pull', 'registry.gitlab.com/mygroup/myrepo'] }); // Pulls Docker images from a registry
}

pullDockerImages().then(() => console.log('Docker images pulled successfully.'));

6. SSH Key Management

npmci also simplifies the management of SSH keys, which is crucial for accessing private repositories and servers.

Preparing SSH Keys:

import { Npmci } from '@ship.zone/npmci';

async function prepareSshKeys() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.sshManager.handleCli({ _: ['ssh', 'prepare'] }); // Prepares SSH keys from environment variables
}

prepareSshKeys().then(() => console.log('SSH keys prepared successfully.'));

7. Cloudron Integration

For users deploying applications on Cloudron, npmci provides a set of utilities for automating Cloudron tasks.

Deploying to Cloudron:

import { Npmci } from '@ship.zone/npmci';

async function deployToCloudron() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.cloudronManager.handleCli({
    _: ['cloudron', 'deploy']
  }); // Deploys application to Cloudron platform
}

deployToCloudron().then(() => console.log('Deployment to Cloudron completed.'));

Preparing Cloudron Manifest: Before deployment, replace version placeholders in the Cloudron Manifest:

import { Npmci } from '@ship.zone/npmci';
import * as fs from 'fs';
import * as path from 'path';

async function prepareCloudronManifest(version: string) {
  const manifestPath = path.join(process.cwd(), "CloudronManifest.json");
  let manifestFile = fs.readFileSync(manifestPath, { encoding: 'utf-8' });
  manifestFile = manifestFile.replace(/##version##/g, version);
  fs.writeFileSync(manifestPath, manifestFile);
  console.log('CloudronManifest prepared');
}

async function deployWithPreparedManifest() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();
  
  await prepareCloudronManifest('1.0.0');
  await npmciInstance.cloudronManager.handleCli({
    _: ['cloudron', 'deploy']
  }); // Deploys application to Cloudron platform
}

deployWithPreparedManifest().then(() => console.log('Deployment to Cloudron with manifest preparation completed.'));

8. Webhook Triggers

npmci supports webhook triggers, allowing you to trigger builds and other activities based on various conditions.

Triggering Webhooks:

import { Npmci } from '@ship.zone/npmci';

async function triggerWebhooks() {
  const npmciInstance = new Npmci();
  await npmciInstance.start();

  await npmciInstance.triggerManager.handleCli({
    _: ['trigger']
  }); // Triggers webhooks based on environment variables
}

triggerWebhooks().then(() => console.log('Webhooks triggered successfully.'));

9. Using the bash Helper

npmci includes a bash helper for executing commands within a bash shell, useful for various custom tasks.

Using bash to Execute Commands:

import { bash } from '@ship.zone/npmci';

async function runCustomBashCommand(command: string) {
  const output = await bash(command);
  console.log('Command output:', output);
}

runCustomBashCommand('echo Hello World').then(() => console.log('Custom command executed successfully.'));

Full Features and Use Cases

Below is a comprehensive set of features and use cases supported by npmci. This section ensures you can take full advantage of the library's capabilities in multiple scenarios.

Comprehensive Docker Workflow

Step-by-step Docker Image Handling:

  1. Detect and Build All Dockerfiles:

    import { Npmci } from '@ship.zone/npmci';
    
    async function detectAndBuildDockerfiles() {
      const npmciInstance = new Npmci();
      await npmciInstance.start();
      const dockerfiles = await npmciInstance.dockerManager.getDockerfiles();
      console.log('Dockerfiles detected:', dockerfiles.map(d => d.filePath));
    
      await npmciInstance.dockerManager.handleCli({ _: ['docker', 'build'] });
      console.log('Dockerfiles built successfully.');
    }
    
    detectAndBuildDockerfiles().then(() => console.log('Docker detection and build process completed.'));
    
  2. Test All Dockerfiles:

    import { Npmci } from '@ship.zone/npmci';
    
    async function testAllDockerfiles() {
      const npmciInstance = new Npmci();
      await npmciInstance.start();
      await npmciInstance.dockerManager.handleCli({ _: ['docker', 'test'] });
      console.log('Dockerfiles tested successfully.');
    }
    
    testAllDockerfiles().then(() => console.log('Docker testing process completed.'));
    
  3. Push Dockerfiles to a Registry:

    import { Npmci } from '@ship.zone/npmci';
    
    async function pushDockerfilesToRegistry() {
      const npmciInstance = new Npmci();
      await npmciInstance.start();
    
      await npmciInstance.dockerManager.handleCli({ _: ['docker', 'push'] });
      console.log('Dockerfiles pushed to registry successfully.');
    }
    
    pushDockerfilesToRegistry().then(() => console.log('Docker push process completed.'));
    

Dockerfile Class Example:

Here's a snippet showcasing how the Dockerfile class can be used to handle Dockerfile-specific operations:

import { Dockerfile } from '@ship.zone/npmci';

async function handleDockerfileOperations() {
  // Initialize Dockerfile instances
  const dockerfile1 = new Dockerfile(/* required parameters */);
  const dockerfile2 = new Dockerfile(/* required parameters */);

  // Read and sort Dockerfiles
  const dockerfiles = await Dockerfile.readDockerfiles(/* required parameters */);
  const sortedDockerfiles = await Dockerfile.sortDockerfiles(dockerfiles);

  // Build and Test Dockerfiles
  await Dockerfile.buildDockerfiles(sortedDockerfiles);
  await Dockerfile.testDockerfiles(sortedDockerfiles);

  // Push Dockerfile images to a registry
  for (const dockerfile of sortedDockerfiles) {
    await dockerfile.push(/* registry and tag parameters */);
  }

  console.log('Dockerfile operations completed successfully.');
}

handleDockerfileOperations().then(() => console.log('Dockerfile processing flow completed.'));

This completes the comprehensive guide to @ship.zone/npmci. With the examples and explanations provided, you should be able to harness the full power and flexibility of the library to streamline your CI/CD processes effectively. undefined