Examples
Runnable examples live in the lexicon’s examples/ directory. Clone the repo and try them:
cd examples/getting-startedbun installchant build # produces .gitlab-ci.ymlchant lint # runs lint rulesbun test # runs the example's testsGetting Started
Section titled “Getting Started”examples/getting-started/ — a 2-stage Node.js pipeline with build and test jobs.
src/├── config.ts # Shared config: image, cache└── pipeline.ts # Job definitions: build, testShared configuration
Section titled “Shared configuration”config.ts extracts reusable objects — image and cache — so jobs stay concise:
/** * Shared pipeline configuration */
import { Image, Cache } from "@intentius/chant-lexicon-gitlab";
// Default image for all jobsexport const defaultImage = new Image({ name: "node:20-alpine",});
// Standard cache configurationexport const npmCache = new Cache({ key: "$CI_COMMIT_REF_SLUG", paths: ["node_modules/"], policy: "pull-push",});Pipeline jobs
Section titled “Pipeline jobs”pipeline.ts defines two jobs that import shared config:
import { Job, Artifacts } from "@intentius/chant-lexicon-gitlab";import { defaultImage, npmCache } from "./config";
export const junitReports = { junit: "coverage/junit.xml" };
export const testArtifacts = new Artifacts({ reports: junitReports, paths: ["coverage/"], expire_in: "1 week",});
export const build = new Job({ stage: "build", image: defaultImage, cache: npmCache, script: ["npm install", "npm run build"],});
export const test = new Job({ stage: "test", image: defaultImage, cache: npmCache, script: ["npm install", "npm test"], artifacts: testArtifacts,});Generated output
Section titled “Generated output”chant build produces this .gitlab-ci.yml:
stages: - build - test
build: stage: build image: name: node:20-alpine cache: key: '$CI_COMMIT_REF_SLUG' paths: - node_modules/ policy: pull-push script: - npm install - npm run build
test: stage: test image: name: node:20-alpine cache: key: '$CI_COMMIT_REF_SLUG' paths: - node_modules/ policy: pull-push script: - npm install - npm test artifacts: reports: junit: coverage/junit.xml paths: - coverage/ expire_in: '1 week'Patterns demonstrated:
- Shared config — reusable image and cache extracted into
config.ts - JUnit reports — test artifacts include JUnit XML for GitLab MR display
- Stage ordering — stages collected automatically from job declarations
Docker Build
Section titled “Docker Build”examples/docker-build/ — builds and pushes a Docker image using the DockerBuild composite.
import { DockerBuild, Job, Image } from "@intentius/chant-lexicon-gitlab";
export const docker = DockerBuild({ dockerfile: "Dockerfile", tagLatest: true,});
export const test = new Job({ stage: "test", image: new Image({ name: "node:22-alpine" }), script: ["node test.js"],});The DockerBuild composite expands to a job with Docker-in-Docker service, registry login, build, and push steps.
Node Pipeline
Section titled “Node Pipeline”examples/node-pipeline/ — a full Node.js CI pipeline using the NodePipeline composite.
import { NodePipeline } from "@intentius/chant-lexicon-gitlab";
export const app = NodePipeline({ nodeVersion: "22", installCommand: "npm install", buildScript: "build", testScript: "test",});Python Pipeline
Section titled “Python Pipeline”examples/python-pipeline/ — a Python CI pipeline using the PythonPipeline composite.
import { PythonPipeline } from "@intentius/chant-lexicon-gitlab";
export const app = PythonPipeline({ pythonVersion: "3.12", lintCommand: null,});Review App
Section titled “Review App”examples/review-app/ — deploys a review environment per merge request using the ReviewApp composite.
import { ReviewApp, Job, Image } from "@intentius/chant-lexicon-gitlab";
export const review = ReviewApp({ name: "review", deployScript: "echo deploy",});
export const test = new Job({ stage: "test", image: new Image({ name: "node:22-alpine" }), script: ["node test.js"],});AWS ALB Deployment
Section titled “AWS ALB Deployment”A cross-lexicon example showing how to deploy AWS CloudFormation stacks from GitLab CI. Three separate pipelines mirror the separate-project AWS ALB pattern:
Infra pipeline
Section titled “Infra pipeline”Deploys the shared ALB stack (VPC, ALB, ECS cluster, ECR repos):
import { Job, Image, Rule } from "@intentius/chant-lexicon-gitlab";
const awsImage = new Image({ name: "amazon/aws-cli:latest" });
export const deployInfra = new Job({ stage: "deploy", image: awsImage, script: [ "aws cloudformation deploy --template-file templates/template.json --stack-name shared-alb --capabilities CAPABILITY_IAM --no-fail-on-empty-changeset", ], rules: [ new Rule({ if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH" }), ],});Service pipeline (API)
Section titled “Service pipeline (API)”Builds a Docker image, pushes to ECR, and deploys the API service stack with cross-stack parameter passing. The full source lives in the cross-lexicon example examples/gitlab-aws-alb-api/:
import { Job, Image, Service, Need, Rule } from "@intentius/chant-lexicon-gitlab";import { CI } from "@intentius/chant-lexicon-gitlab";
const ECR_URL = "$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com";const ECR_REPO = "alb-api";const STACK_NAME = "shared-alb-api";const INFRA_STACK = "shared-alb";const fullImage = `${ECR_URL}/${ECR_REPO}`;
const awsImage = new Image({ name: "amazon/aws-cli:latest", entrypoint: [""] });const dockerImage = new Image({ name: "docker:27-cli" });const dind = new Service({ name: "docker:27-dind", alias: "docker" });
const defaultBranchOnly = [ new Rule({ if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH" }),];
const dockerVariables = { DOCKER_TLS_CERTDIR: "/certs" };
export const buildImage = new Job({ stage: "build", image: dockerImage, services: [dind], variables: dockerVariables, before_script: [ "apk add --no-cache aws-cli", `aws ecr get-login-password | docker login --username AWS --password-stdin ${ECR_URL}`, ], script: [ `docker build -t ${fullImage}:${CI.CommitRefSlug} .`, `docker push ${fullImage}:${CI.CommitRefSlug}`, `if [ "${CI.CommitBranch}" = "${CI.DefaultBranch}" ]; then docker tag ${fullImage}:${CI.CommitRefSlug} ${fullImage}:latest && docker push ${fullImage}:latest; fi`, ], rules: defaultBranchOnly,});
export const deployService = new Job({ stage: "deploy", image: awsImage, needs: [new Need({ job: "build-image" })], script: [ `OUTPUTS=$(aws cloudformation describe-stacks --stack-name ${INFRA_STACK} --query 'Stacks[0].Outputs' --output json)`, `PARAMS=$(echo "$OUTPUTS" | jq -r '[(.[] | select(.OutputKey == "ClusterArn") | "clusterArn=" + .OutputValue), (.[] | select(.OutputKey == "ListenerArn") | "listenerArn=" + .OutputValue), (.[] | select(.OutputKey == "AlbSgId") | "albSgId=" + .OutputValue), (.[] | select(.OutputKey == "ExecutionRoleArn") | "executionRoleArn=" + .OutputValue), (.[] | select(.OutputKey == "VpcId") | "vpcId=" + .OutputValue), (.[] | select(.OutputKey == "PrivateSubnet1") | "privateSubnet1=" + .OutputValue), (.[] | select(.OutputKey == "PrivateSubnet2") | "privateSubnet2=" + .OutputValue)] | join(" ")')`, `IMAGE_URI=$(echo "$OUTPUTS" | jq -r '.[] | select(.OutputKey == "ApiRepoUri") | .OutputValue'):\${CI_COMMIT_REF_SLUG}`, `aws cloudformation deploy --template-file templates/template.json --stack-name ${STACK_NAME} --capabilities CAPABILITY_IAM --no-fail-on-empty-changeset --parameter-overrides $PARAMS image=$IMAGE_URI`, ], rules: defaultBranchOnly,});Key patterns:
- ECR login — uses
aws ecr get-login-passwordinstead of GitLab registry credentials - Cross-stack parameter passing —
describe-stacksfetches outputs from the infra stack,jqmaps them to--parameter-overrides - Job naming —
buildImageserializes tobuild-imagein YAML;Needreferences must use kebab-case - Docker-in-Docker —
docker:27-cliimage withdocker:27-dindservice for container builds
The full examples live in examples/gitlab-aws-alb-infra/, examples/gitlab-aws-alb-api/, and examples/gitlab-aws-alb-ui/.