206 lines
6 KiB
YAML
206 lines
6 KiB
YAML
# Define pipeline inputs for runtime configuration
|
|
spec:
|
|
inputs:
|
|
gpg_passphrase:
|
|
description: "Passphrase for GPG signing key"
|
|
type: string
|
|
default: ""
|
|
|
|
---
|
|
|
|
stages:
|
|
- configure
|
|
- build
|
|
- test
|
|
- package
|
|
- encrypt
|
|
- publish
|
|
|
|
# Set variables used for builds in CI, should probably set this in the build container if possible
|
|
variables:
|
|
AF_PATH: /usr/local
|
|
# Use Docker-outside-of-Docker (DooD) by mounting the host's Docker socket
|
|
DOCKER_HOST: unix:///var/run/docker.sock
|
|
# Disable TLS as we're using the local socket
|
|
DOCKER_TLS_CERTDIR: ""
|
|
DOCKER_AUTH_CONFIG: '{"auths":{"gl.whitefoxdefense.com:5050":{"auth":"Z2l0bGFiK2RlcGxveS10b2tlbi04OmdsZHQtSnNiVFFoeXhpUWNxcHFXMndfYjY="}}}'
|
|
LD_LIBRARY_PATH: /usr/local/lib
|
|
# Experimental for the EKS runner
|
|
# DOCKER_HOST: "tcp://docker:2375"
|
|
|
|
# Dynamically pull the build container image name from the devcontainer.json file.
|
|
# This acts as a single-source-of-truth to keep local and CI builds unified.
|
|
configure:
|
|
stage: configure
|
|
image: alpine:latest
|
|
script:
|
|
- BUILD_IMAGE=$(grep '"image":' .devcontainer/devcontainer.json | cut -d '"' -f 4)
|
|
- printf 'BUILD_IMAGE=%s' "$BUILD_IMAGE" > build_image.env
|
|
- ls -la build_image.env
|
|
- cat build_image.env
|
|
artifacts:
|
|
reports:
|
|
dotenv: build_image.env
|
|
tags:
|
|
- test-ci-cd
|
|
|
|
# Build the Rust application using Nix
|
|
build:
|
|
stage: build
|
|
image: nixos/nix:latest
|
|
before_script:
|
|
# Enable flakes and nix-command
|
|
- mkdir -p ~/.config/nix
|
|
- echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
|
|
script:
|
|
# Generate Cargo.lock if it doesn't exist
|
|
- nix develop --command cargo generate-lockfile || true
|
|
# Build the Rust application
|
|
- nix build .#app
|
|
# Copy the result for artifacts
|
|
- mkdir -p build-output
|
|
- cp -rL result/* build-output/ || cp result build-output/hello-world
|
|
artifacts:
|
|
paths:
|
|
- build-output/
|
|
- Cargo.lock
|
|
expire_in: 1 hour
|
|
tags:
|
|
- test-ci-cd
|
|
|
|
# Test the application
|
|
test:
|
|
stage: test
|
|
image: nixos/nix:latest
|
|
before_script:
|
|
- mkdir -p ~/.config/nix
|
|
- echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
|
|
script:
|
|
# Run the application in a Nix shell with all dependencies
|
|
- nix develop --command cargo test
|
|
# You could also run the binary here if needed
|
|
# - nix run .#app
|
|
dependencies:
|
|
- build
|
|
tags:
|
|
- test-ci-cd
|
|
|
|
# Build Docker image using Nix and load it into Docker (DooD pattern)
|
|
package-docker-image-with-nix:
|
|
stage: package
|
|
image: nixos/nix:latest
|
|
before_script:
|
|
# Install Docker CLI in the Nix container
|
|
- nix-env -iA nixpkgs.docker
|
|
# Enable flakes
|
|
- mkdir -p ~/.config/nix
|
|
- echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
|
|
script:
|
|
# Build the Docker image using Nix
|
|
- nix build .#docker
|
|
# Load the image into Docker daemon (running on host via socket)
|
|
- docker load < result
|
|
# Tag the image
|
|
- docker tag hello-world:latest hello-world:${CI_COMMIT_SHORT_SHA}
|
|
# Test run the container
|
|
- docker run --rm hello-world:latest
|
|
# Optional: Push to registry if configured
|
|
# - docker tag hello-world:latest ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
|
|
# - docker push ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
|
|
dependencies:
|
|
- build
|
|
tags:
|
|
- test-ci-cd
|
|
# This job requires a GitLab runner with Docker socket access
|
|
# The runner should have /var/run/docker.sock mounted
|
|
|
|
# Alternative: Build using Docker directly (DooD)
|
|
package-docker-image:
|
|
stage: package
|
|
image: docker:latest
|
|
services: [] # No dind service
|
|
variables:
|
|
DOCKER_HOST: unix:///var/run/docker.sock
|
|
before_script:
|
|
# Verify Docker access
|
|
- docker info
|
|
script:
|
|
- docker build -t hello-world:traditional-${CI_COMMIT_SHORT_SHA} .
|
|
- docker run --rm hello-world:traditional-${CI_COMMIT_SHORT_SHA}
|
|
- docker save -o hello-world.tar.gz hello-world:traditional-${CI_COMMIT_SHORT_SHA}
|
|
dependencies:
|
|
- build
|
|
tags:
|
|
- test-ci-cd
|
|
only:
|
|
- branches
|
|
artifacts:
|
|
expire_in: 1 week
|
|
name: wf-image-dood-$BUILD_VARIANT-$CI_COMMIT_BRANCH-$CI_COMMIT_SHORT_SHA
|
|
paths:
|
|
- ./hello-world.tar.gz
|
|
|
|
encrypt:
|
|
stage: encrypt
|
|
image: alpine:latest
|
|
needs:
|
|
- job: package-docker-image
|
|
artifacts: true
|
|
before_script:
|
|
- apk add --no-cache gnupg
|
|
script:
|
|
- |
|
|
if [ -n "$GPG_PRIVATE_KEY" ]; then
|
|
gpg --batch --import "$GPG_PRIVATE_KEY"
|
|
else
|
|
echo "Warning: GPG_PRIVATE_KEY not set. Using existing keyring."
|
|
fi
|
|
- echo "$GPG_PUBLIC_KEY" | gpg --import
|
|
- |
|
|
echo 'DD0007338E2C43BD553D569377D9D93F96483723:6:' | gpg --import-ownertrust
|
|
- echo "Encrypting hello-world.tar.gz..."
|
|
- printf '%s' '$[[ inputs.gpg_passphrase ]]' > passphrase.txt
|
|
- |
|
|
gpg --batch --yes \
|
|
--pinentry-mode loopback \
|
|
--passphrase-file passphrase.txt \
|
|
--sign --default-key B35BF119FC3AE04C \
|
|
--encrypt -r 6C4C078A1C72925E \
|
|
-o hello-world.tar.gz.gpg \
|
|
hello-world.tar.gz
|
|
- |
|
|
if [ -f "hello-world.tar.gz.gpg" ]; then
|
|
echo "Encryption successful!"
|
|
ls -lh hello-world.tar.gz.gpg
|
|
else
|
|
echo "Error: Encrypted file not created"
|
|
exit 1
|
|
fi
|
|
artifacts:
|
|
expire_in: 1 week
|
|
name: encrypted-image-$CI_COMMIT_SHORT_SHA
|
|
paths:
|
|
- hello-world.tar.gz.gpg
|
|
tags:
|
|
- test-ci-cd
|
|
|
|
publish_gpg:
|
|
stage: publish
|
|
image: curlimages/curl:8.5.0
|
|
# If any build variant fails, this job will not publish any artifacts.
|
|
needs:
|
|
- job: encrypt
|
|
artifacts: true
|
|
script:
|
|
# Version scheme: CI-only versions are easy to identify + clean up later
|
|
- PKG_NAME="hello-world.tar.gz.gpg"
|
|
- FILE="./hello-world.tar.gz.gpg"
|
|
|
|
- PKG_VERSION="${CI_COMMIT_SHORT_SHA}-${CI_PIPELINE_IID}"
|
|
- echo "Uploading ${FILE} as ${PKG_NAME} ${PKG_VERSION}"
|
|
|
|
- |
|
|
curl --fail \
|
|
--header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
|
|
--upload-file "${FILE}" \
|
|
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PKG_NAME}/${PKG_VERSION}/$(basename "${FILE}")"
|