← Back to Use Cases
SCHEDULED JOBS & PIPELINES

CI/CD State

Pass data between pipeline stages. No artifacts, no environment variables.

The Problem

Your build pipeline has multiple stages: build, test, and deploy. The build stage generates a version number and build metadata that the deploy stage needs.

Managing artifacts or juggling environment variables between stages is tedious. You just need to pass a few values forward.

The WrenDB Solution

Store build metadata in WrenDB during the build stage, then retrieve it in deployment. Simple HTTP, works with any CI system.

GitHub Actions Example

.github/workflows/deploy.yml
name: Build and Deploy

on:
  push:
    branches: [main]

env:
  WREN_STASH_ID: ${{ secrets.WREN_STASH_ID }}
  WREN_TOKEN: ${{ secrets.WREN_TOKEN }}

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Build application
        run: |
          npm run build
          VERSION=$(node -p "require('./package.json').version")
          BUILD_HASH=$(git rev-parse --short HEAD)
          echo "Built version $VERSION ($BUILD_HASH)"

      - name: Save build metadata to WrenDB
        run: |
          BUILD_DATA=$(cat <<EOF
          {
            "version": "$VERSION",
            "commit": "$BUILD_HASH",
            "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
            "branch": "${{ github.ref_name }}"
          }
          EOF
          )

          curl -X POST https://wrendb.com/api/item/$WREN_STASH_ID \
            -H "Authorization: Bearer $WREN_TOKEN" \
            -H "Content-Type: application/json" \
            -d "$BUILD_DATA"

  test:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm test

  deploy:
    needs: [build, test]
    runs-on: ubuntu-latest
    steps:
      - name: Get build metadata from WrenDB
        id: metadata
        run: |
          BUILD_DATA=$(curl -s https://wrendb.com/api/stash/$WREN_STASH_ID/items/latest)
          echo "version=$(echo $BUILD_DATA | jq -r '.version')" >> $GITHUB_OUTPUT
          echo "commit=$(echo $BUILD_DATA | jq -r '.commit')" >> $GITHUB_OUTPUT
          echo "Deploying version: $(echo $BUILD_DATA | jq -r '.version')"

      - name: Deploy to production
        run: |
          echo "Deploying ${{ steps.metadata.outputs.version }}"
          echo "Commit: ${{ steps.metadata.outputs.commit }}"
          # Your deployment commands here...

GitLab CI Example

.gitlab-ci.yml
stages:
  - build
  - test
  - deploy

variables:
  WREN_BASE: "https://wrendb.com/api/item/$WREN_STASH_ID"

build:
  stage: build
  script:
    - npm run build
    - VERSION=$(node -p "require('./package.json').version")
    - BUILD_ID="${CI_PIPELINE_ID}-${CI_COMMIT_SHORT_SHA}"

    # Store build info
    - |
      curl -X POST $WREN_BASE/build-$BUILD_ID \
        -H "Authorization: Bearer $WREN_TOKEN" \
        -H "Content-Type: application/json" \
        -d "{
          \"version\": \"$VERSION\",
          \"pipeline_id\": \"$CI_PIPELINE_ID\",
          \"commit\": \"$CI_COMMIT_SHORT_SHA\",
          \"branch\": \"$CI_COMMIT_BRANCH\"
        }"

    # Also store as 'latest' for easy retrieval
    - echo "$BUILD_ID" | curl -X POST $WREN_BASE/latest-build-id \
        -H "Authorization: Bearer $WREN_TOKEN" \
        -d @-

test:
  stage: test
  script:
    - npm test

deploy:
  stage: deploy
  script:
    # Get the build ID from the build stage
    - BUILD_ID=$(curl -s $WREN_BASE/latest-build-id)

    # Retrieve full build metadata
    - BUILD_INFO=$(curl -s $WREN_BASE/build-$BUILD_ID)
    - VERSION=$(echo $BUILD_INFO | jq -r '.version')
    - COMMIT=$(echo $BUILD_INFO | jq -r '.commit')

    - echo "Deploying version $VERSION (commit $COMMIT)"
    - # Your deployment commands...

Jenkins Example

Jenkinsfile
pipeline {
    agent any

    environment {
        WREN_STASH_ID = credentials('wren-stash-id')
        WREN_TOKEN = credentials('wren-token')
        BUILD_KEY = "build-${env.BUILD_ID}"
    }

    stages {
        stage('Build') {
            steps {
                sh 'npm run build'

                script {
                    def version = sh(
                        script: 'node -p "require(\'./package.json\').version"',
                        returnStdout: true
                    ).trim()

                    def buildData = """
                    {
                        "version": "${version}",
                        "build_id": "${env.BUILD_ID}",
                        "timestamp": "${new Date().format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'')}",
                        "branch": "${env.GIT_BRANCH}"
                    }
                    """

                    sh """
                        curl -X POST https://wrendb.com/api/item/\$WREN_STASH_ID/${BUILD_KEY} \\
                          -H "Authorization: Bearer \$WREN_TOKEN" \\
                          -H "Content-Type: application/json" \\
                          -d '${buildData}'
                    """
                }
            }
        }

        stage('Test') {
            steps {
                sh 'npm test'
            }
        }

        stage('Deploy') {
            steps {
                script {
                    def buildInfo = sh(
                        script: """
                            curl -s https://wrendb.com/api/item/\$WREN_STASH_ID/${BUILD_KEY}
                        """,
                        returnStdout: true
                    ).trim()

                    def metadata = readJSON text: buildInfo

                    echo "Deploying version: ${metadata.version}"
                    echo "Build ID: ${metadata.build_id}"

                    // Your deployment logic here
                }
            }
        }
    }
}

Why This Works

  • Works with any CI system - Just HTTP calls, no plugins needed
  • No artifact management - No need to upload/download files between stages
  • Easy to debug - Curl the endpoint to see what data was passed
  • Auto-cleanup - Old build metadata expires automatically after 30 days

Pro Tips

  • Use unique keys like build-${BUILD_ID} to avoid conflicts between concurrent builds
  • Store a "latest" pointer to easily find the most recent build metadata
  • Use JSON for structured metadata - makes it easy to extract specific fields

Related Use Cases

Build Badge Data - Store pass/fail status for README badges Cron Memories - Remember state between scheduled runs