12 KiB
# @ship.zone/npmci
node and docker in gitlab ci on steroids
## Install
To install `@ship.zone/npmci`, you can use npm or yarn:
```sh
# 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. 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.'));
2. 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.'));
3. 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.'));
4. 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.'));
5. 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.'));
6. 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.'));
7. 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.'));
8. 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.'));
9. Example CI Configuration
An example of integrating npmci
into a GitLab CI configuration might 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
- npmci cloudron deploy
environment:
name: production
url: http://example.com
This example YAML file configures stages for preparing the environment, building the project, running tests, and deploying the project. npmci
commands are used throughout to handle various tasks.
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:
-
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.'));
-
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.'));
-
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