Skip to content
obsidian-ci-integration logo

Obsidian CI Integration

obsidian-ci-integration

Set up GitHub Actions CI/CD for Obsidian plugin development. Use when automating builds, tests, and releases for your plugin, or setting up continuous integration for Obsidian projects. Trigger with phrases like "obsidian CI", "obsidian github actions", "obsidian automated build", "obsidian CI/CD".

SKILL.md

Full skill instructions

Obsidian CI Integration

Overview

Set up GitHub Actions for automated building, testing, and releasing Obsidian plugins.

Prerequisites

  • GitHub repository for your plugin
  • Working local build (npm run build)
  • Basic understanding of GitHub Actions

Instructions

Step 1: Create Build Workflow

# .github/​workflows/​build.yml
name: Build Obsidian Plugin

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/​checkout@v4

      - name: Setup Node.js
        uses: actions/​setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint
        continue-on-error: true

      - name: Type check
        run: npm run typecheck
        if: always()

      - name: Build
        run: npm run build

      - name: Upload build artifacts
        uses: actions/​upload-artifact@v4
        with:
          name: plugin-build
          path: |
            main.js
            manifest.json
            styles.css
          if-no-files-found: error

Step 2: Create Test Workflow

# .github/​workflows/​test.yml
name: Test

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/​checkout@v4

      - name: Setup Node.js
        uses: actions/​setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test -- --coverage

      - name: Upload coverage
        uses: codecov/​codecov-action@v4
        with:
          files: ./​coverage/​lcov.info
          fail_ci_if_error: false

Step 3: Create Release Workflow

# .github/​workflows/​release.yml
name: Release Obsidian Plugin

on:
  push:
    tags:
      - '*'

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/​checkout@v4

      - name: Setup Node.js
        uses: actions/​setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Get version
        id: version
        run: echo "version=$(jq -r '.version' manifest.json)" >> $GITHUB_OUTPUT

      - name: Verify tag matches version
        run: |
          TAG_VERSION="${GITHUB_REF#refs/​tags/​}"
          MANIFEST_VERSION="${{ steps.version.outputs.version }}"
          if [ "$TAG_VERSION" != "$MANIFEST_VERSION" ]; then
            echo "Tag ($TAG_VERSION) does not match manifest version ($MANIFEST_VERSION)"
            exit 1
          fi

      - name: Create release archive
        run: |
          mkdir release
          cp main.js manifest.json release/
          [ -f styles.css ] && cp styles.css release/
          cd release && zip -r ../​my-plugin-${{ steps.version.outputs.version }}.zip *

      - name: Create GitHub Release
        uses: softprops/​action-gh-release@v1
        with:
          files: |
            main.js
            manifest.json
            styles.css
            my-plugin-${{ steps.version.outputs.version }}.zip
          generate_release_notes: true
          draft: false
          prerelease: false

Step 4: Add Version Bump Script

// version-bump.mjs
import { readFileSync, writeFileSync } from "fs";

const targetVersion = process.argv[2];
if (!targetVersion) {
  console.error("Usage: node version-bump.mjs <version>");
  process.exit(1);
}

// Validate semver
if (!/^\d+\.\d+\.\d+$/​.test(targetVersion)) {
  console.error("Invalid version format. Use semver: x.y.z");
  process.exit(1);
}

// Update manifest.json
const manifest = JSON.parse(readFileSync("manifest.json", "utf8"));
const { minAppVersion } = manifest;
manifest.version = targetVersion;
writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t"));

// Update versions.json
let versions = {};
try {
  versions = JSON.parse(readFileSync("versions.json", "utf8"));
} catch {
  // File doesn't exist, create new
}
versions[targetVersion] = minAppVersion;
writeFileSync("versions.json", JSON.stringify(versions, null, "\t"));

// Update package.json
const pkg = JSON.parse(readFileSync("package.json", "utf8"));
pkg.version = targetVersion;
writeFileSync("package.json", JSON.stringify(pkg, null, "\t"));

console.log(`Version bumped to ${targetVersion}`);

Step 5: Configure package.json Scripts

{
  "scripts": {
    "dev": "node esbuild.config.mjs",
    "build": "node esbuild.config.mjs production",
    "test": "vitest run",
    "test:watch": "vitest",
    "lint": "eslint src/ --ext .ts",
    "typecheck": "tsc --noEmit",
    "version": "node version-bump.mjs && git add manifest.json versions.json package.json",
    "release": "npm run version && git commit -m 'Bump version' && git push && git push --tags"
  }
}

Step 6: Create Validation Workflow

# .github/​workflows/​validate.yml
name: Validate Plugin

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]

jobs:
  validate:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/​checkout@v4

      - name: Validate manifest.json
        run: |
          # Check required fields
          for field in id name version minAppVersion description author; do
            value=$(jq -r ".$field" manifest.json)
            if [ "$value" == "null" ] || [ -z "$value" ]; then
              echo "ERROR: Missing required field: $field"
              exit 1
            fi
          done

          # Validate version format
          version=$(jq -r '.version' manifest.json)
          if ! [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
            echo "ERROR: Invalid version format: $version"
            exit 1
          fi

          echo "manifest.json is valid"

      - name: Validate versions.json
        run: |
          if [ ! -f versions.json ]; then
            echo "ERROR: versions.json not found"
            exit 1
          fi

          # Validate JSON syntax
          if ! jq empty versions.json; then
            echo "ERROR: Invalid JSON in versions.json"
            exit 1
          fi

          # Check current version is in versions.json
          current=$(jq -r '.version' manifest.json)
          if [ "$(jq -r ".[\"$current\"]" versions.json)" == "null" ]; then
            echo "WARNING: Current version $current not in versions.json"
          fi

          echo "versions.json is valid"

      - name: Check for console.log
        run: |
          count=$(grep -r "console.log" src/ --include="*.ts" | wc -l || true)
          if [ "$count" -gt 5 ]; then
            echo "WARNING: Found $count console.log statements (consider removing before release)"
          fi

Output

  • Build workflow for CI validation
  • Test workflow with coverage reporting
  • Release workflow for automated GitHub releases
  • Version bump script for consistent versioning
  • Validation workflow for plugin standards

Error Handling

ErrorCauseSolution
Build failsMissing dependenciesEnsure package-lock.json is committed
Release failsVersion mismatchRun version bump before tagging
Upload failsFile not foundCheck build output paths
Permission deniedToken scopeCheck workflow permissions

Examples

Manual Release Process

# 1. Bump version
npm run version 1.0.1

# 2. Commit and tag
git add -A
git commit -m "Release v1.0.1"
git tag 1.0.1

# 3. Push (triggers release workflow)
git push && git push --tags

Beta Release Workflow

# .github/​workflows/​beta.yml
name: Beta Release

on:
  push:
    branches: [beta]

jobs:
  beta:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/​checkout@v4
      - uses: actions/​setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
      - run: npm ci
      - run: npm run build

      - name: Create beta release
        uses: softprops/​action-gh-release@v1
        with:
          tag_name: beta
          prerelease: true
          files: |
            main.js
            manifest.json
          body: |
            Beta release from ${{ github.sha }}
            Install via BRAT: `username/​repo-name` with beta tag

Resources

Next Steps

For publishing to community plugins, see obsidian-deploy-integration.

More skills from Dicklesworthstone

environment-setup-guide logo
Dicklesworthstone/pi_agent_rust

environment-setup-guide

Guide developers through setting up development environments with proper tools, dependencies, and configurations

1.8K 0
View
exa-policy-guardrails logo
Dicklesworthstone/pi_agent_rust

exa-policy-guardrails

Implement Exa lint rules, policy enforcement, and automated guardrails. Use when setting up code quality rules for Exa integrations, implementing pre-commit hooks, or configuring CI policy checks for Exa best practices. Trigger with phrases like "exa policy", "exa lint", "exa guardrails", "exa be...

1.8K 0
View
documenso-ci-integration logo
Dicklesworthstone/pi_agent_rust

documenso-ci-integration

Configure CI/CD pipelines for Documenso integrations. Use when setting up automated testing, deployment pipelines, or continuous integration for Documenso projects. Trigger with phrases like "documenso CI", "documenso GitHub Actions", "documenso pipeline", "documenso automated testing".

1.8K 0
View
openrouter-model-availability logo
Dicklesworthstone/pi_agent_rust

openrouter-model-availability

Build check model availability and implement fallback chains. Use when building resilient systems or handling model outages. Trigger with phrases like 'openrouter availability', 'openrouter fallback', 'openrouter model down', 'openrouter health check'.

1.8K 0
View
langfuse-enterprise-rbac logo
Dicklesworthstone/pi_agent_rust

langfuse-enterprise-rbac

Configure Langfuse enterprise organization management and access control. Use when implementing team access controls, configuring organization settings, or setting up role-based permissions for Langfuse projects. Trigger with phrases like "langfuse RBAC", "langfuse teams", "langfuse organization"...

1.8K 0
View
cursor-compliance-audit logo
Dicklesworthstone/pi_agent_rust

cursor-compliance-audit

Execute compliance and security auditing for Cursor usage. Triggers on "cursor compliance", "cursor audit", "cursor security review", "cursor soc2", "cursor gdpr". Use when analyzing or auditing cursor compliance audit. Trigger with phrases like "cursor compliance audit", "cursor audit", "cursor".

1.8K 0
View
apollo-ci-integration logo
Dicklesworthstone/pi_agent_rust

apollo-ci-integration

Configure Apollo.io CI/CD integration. Use when setting up automated testing, continuous integration, or deployment pipelines for Apollo integrations. Trigger with phrases like "apollo ci", "apollo github actions", "apollo pipeline", "apollo ci/cd", "apollo automated tests".

1.8K 0
View
python-script logo
Dicklesworthstone/pi_agent_rust

python-script

Create robust Python automation with full logging and safety checks. Use when tasks need complex data processing, authenticated API work, conditional file operations, or error handling beyond simple shell commands.

1.8K 0
View
posthog-multi-env-setup logo
Dicklesworthstone/pi_agent_rust

posthog-multi-env-setup

Configure PostHog across development, staging, and production environments. Use when setting up multi-environment deployments, configuring per-environment secrets, or implementing environment-specific PostHog configurations. Trigger with phrases like "posthog environments", "posthog staging", "po...

1.8K 0
View
ai-agents-architect logo
Dicklesworthstone/pi_agent_rust

ai-agents-architect

Expert in designing and building autonomous AI agents. Masters tool use, memory systems, planning strategies, and multi-agent orchestration. Use when: build agent, AI agent, autonomous agent, tool use, function calling.

1.8K 0
View
insecure-deserialization-checker logo
Dicklesworthstone/pi_agent_rust

insecure-deserialization-checker

Validate insecure deserialization checker operations. Auto-activating skill for Security Fundamentals. Triggers on: insecure deserialization checker, insecure deserialization checker Part of the Security Fundamentals skill category. Use when working with insecure deserialization checker functiona...

1.8K 0
View
path-traversal-finder logo
Dicklesworthstone/pi_agent_rust

path-traversal-finder

Manage path traversal finder operations. Auto-activating skill for Security Fundamentals. Triggers on: path traversal finder, path traversal finder Part of the Security Fundamentals skill category. Use when working with path traversal finder functionality. Trigger with phrases like "path traversa...

1.8K 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View