Implementing CI/CD Pipelines for Metadata with Version Control: A Metadata-as-Code Guide
The GoogleCloudPlatform/knowledge-catalog repository enables implementing CI/CD pipelines for metadata with version control by treating YAML and Markdown metadata files as source code artifacts, using the kcmd CLI to validate, snapshot test, and idempotently push changes to Google Cloud Knowledge Catalog.
The Knowledge Catalog repository adopts a Metadata-as-Code philosophy that positions metadata definitions as first-class source artifacts. By storing catalog definitions in Git alongside application code, data teams can apply standard DevOps practices—automated testing, peer review, and continuous deployment—to manage data assets at scale. This approach centers on the kcmd library and CLI tools found in the toolbox/mdcode directory, allowing you to version, validate, and deploy metadata with the same rigor as application code.
Metadata-as-Code Repository Structure
The architecture mirrors the resource hierarchy of underlying data assets to ensure both human readability and automation compatibility.
Catalog Manifest and Entry Files
At the repository root, the catalog.yaml manifest defines the scope of the catalog—such as a BigQuery dataset or user-managed EntryGroup—and enumerates the entry types, aspects, and links to be captured. Beneath the catalog/ directory, each entry is represented by a YAML file (<entry-id>.yaml) alongside optional Markdown side-car files (<entry-id>.overview.md) for unstructured aspects like overviews.
This structure is documented in toolbox/mdcode/docs/concept.md and exemplified in toolbox/mdcode/README.md, ensuring that changes to the scope or included aspects are tracked atomically alongside the entry files.
CI/CD Pipeline Components
A robust pipeline for metadata requires three core stages to ensure safety and consistency before deployment to production.
Static Validation
The lint step verifies YAML syntax integrity, validates required fields against the schema, and ensures that Markdown side-car files contain properly formatted front-matter. This prevents malformed metadata from entering the catalog and failing at runtime.
Snapshot Testing and Drift Detection
Using the kcmd library, the pipeline executes kcmd pull --dry-run to capture the current state from Knowledge Catalog and compare it against the repository version. If unexpected drift is detected—indicating out-of-band changes in the catalog—the CI build fails, triggering human review before any write operations occur.
The expected pull behavior is illustrated in toolbox/mdcode/tests/scenarios/pull_basic.yaml.
Idempotent Push Deployment
Upon successful validation, the pipeline invokes kcmd push to publish metadata changes. This operation is idempotent and respects the --dry-run flag for safety testing before actual deployment. The push command publishes new entries and updates existing ones atomically, ensuring the catalog state converges to the repository definition.
The push operation schema is demonstrated in toolbox/mdcode/tests/scenarios/push_new_entry.yaml.
Implementing the CI/CD Workflow
A production-ready pipeline orchestrates validation and deployment through environment-specific stages using standard CI/CD platforms.
GitHub Actions Configuration
The following workflow file (.github/workflows/metadata-ci.yml) demonstrates the complete lifecycle from validation to deployment:
name: Metadata CI/CD
on:
push:
paths:
- 'toolbox/mdcode/**'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install kcmd
run: npm install kcmd
- name: Lint YAML/MD
run: |
npx yaml-lint toolbox/mdcode/**/**/*.yaml
markdownlint toolbox/mdcode/**/**/*.md
- name: Pull latest catalog snapshot
run: |
npx kcmd pull --dry-run
- name: Run unit tests
run: npm test
deploy:
needs: validate
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install kcmd
run: npm install kcmd
- name: Push metadata
env:
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }}
run: |
npx kcmd push
Environment-Specific Deployment
The deploy job triggers only on the main branch after successful validation, using GOOGLE_APPLICATION_CREDENTIALS stored as repository secrets to authenticate push operations against the Google Cloud API.
Conflict Detection and Resolution
When concurrent edits occur in Knowledge Catalog outside the repository workflow, kcmd pull surfaces conflicts during the snapshot phase. The CI step automatically aborts the push operation, prompting developers to reconcile changes via a pull request. This mechanism prevents accidental overwrites of metadata modified outside the version-controlled pipeline, ensuring that the repository remains the single source of truth.
Programmatic Metadata Management
Beyond CLI usage, the kcmd library supports TypeScript-based automation for complex transformations and bulk updates within CI jobs:
import * as kcmd from 'kcmd';
// Load an existing snapshot
const snapshot = kcmd.CatalogSnapshot.fromPath('/path/to/root');
// Modify an entry programmatically
const entry = snapshot.getEntry('my_dataset.my_table');
entry.resource.description = 'Updated description by CI pipeline';
await snapshot.push(); // Publishes the change
This programmatic approach enables sophisticated CI logic, such as automatically updating metadata based on schema changes detected in upstream data sources.
Summary
- Store metadata as code in a Git repository to enable version control and audit trails through standard Git operations like branch, merge, and revert.
- Validate metadata using static linting of YAML and Markdown files before allowing deployment to catch syntax errors and schema violations early.
- Detect drift using
kcmd pull --dry-runto ensure the repository state matches the actual Knowledge Catalog state before pushing changes. - Deploy safely with the idempotent
kcmd pushcommand, which supports--dry-runtesting and atomic updates to prevent partial state corruption. - Handle conflicts by aborting pushes when drift is detected, forcing reconciliation through pull requests rather than silent overwrites.
Frequently Asked Questions
How does the kcmd push command handle partial failures during deployment?
The kcmd push operation is designed to be atomic and idempotent. If any part of the metadata update fails validation or encounters a permissions error, the entire transaction is aborted, preventing partial updates that could leave the catalog in an inconsistent state. You can verify behavior before execution by running kcmd push --dry-run to simulate the changes.
Can I use kcmd with CI/CD platforms other than GitHub Actions?
Yes, the kcmd library and CLI are platform-agnostic Node.js tools that execute in any environment supporting Node.js 20 or higher. You can integrate the same kcmd pull and kcmd push commands into GitLab CI, CircleCI, Jenkins, or Azure DevOps pipelines by installing the package via npm install kcmd and configuring the appropriate authentication credentials.
What authentication method does kcmd require for Google Cloud deployment?
kcmd uses standard Google Cloud Application Default Credentials. In CI/CD environments, you must provide a service account key via the GOOGLE_APPLICATION_CREDENTIALS environment variable, as shown in the workflow example. Ensure the service account has the necessary Knowledge Catalog roles (such as datacatalog.entries.update) to perform push operations.
How do I initialize a new metadata repository from an existing BigQuery dataset?
Use the kcmd init command with the --bigquery-dataset flag to scaffold the initial catalog structure from an existing dataset. After initialization, commit the generated files to your repository and proceed with the standard CI/CD validation workflow to manage future changes through version control.
# Initialize a new snapshot for a BigQuery dataset
kcmd init --bigquery-dataset my-project.sales_data
# Pull the latest state from the service (dry-run first)
kcmd pull --dry-run
# After review, push changes to Knowledge Catalog
kcmd push
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →