Skills on Tessl: a developer-grade package manager for agent skillsLearn more
Logo
Back to articlesThe CI/CD of Agent Skills: Automate Publishing with GitHub Actions

11 Feb 20266 minute read

Simon Maple

Simon Maple is Tessl’s Founding Developer Advocate, a Java Champion, and former DevRel leader at Snyk, ZeroTurnaround, and IBM.

You’ve built a brilliant skill. Bump the version, package it, authenticate, upload… and then spot it: you forgot to update the manifest summary. Again. Third time this week.

Manual publishing usually looks like this:

  1. Make changes to your artifact
  2. Remember to bump the version
  3. Package the files
  4. Authenticate with the API
  5. Upload the package
  6. Realise you shipped the wrong thing anyway:
    1. forgot to update the manifest/summary
    2. packaged stale files from an old build directory
    3. bumped the version but published from the wrong branch
    4. auth token expired mid-upload, leaving a half-published release
    5. everything “worked”… until a user installs it and hits a runtime error 🫠

Why You Need CI/CD for your Agent Context

A stale skill doesn't just sit there - it actively teaches agents the wrong patterns. When your team updated that API last month but nobody re-published the skill, every agent in every repo is now generating code against deprecated endpoints. CI/CD for skills isn't nice-to-have; it's how you prevent context debt from compounding silently.

Tessl is our answer to that problem - a package manager for skills and context. It gives us a repeatable way to publish “tiles” (packages of context that can include skills, docs, and rules - see image below)to the Tessl Registry, so every version changes are tracked and reflected in your tile.

image2

How do you publish and update your agent skills?

tesslio/publish is a simple workflow that adds automatic publishing of Tessl tiles to your repository. This is done as a GitHub action, as follows:

how to publish

This ensures every push to main automatically publishes your tile, so long as the tile version has changed. The action checks if your version already exists in the Tessl registry. If it does, the publish step is skipped gracefully:

myworkspace/my-tile@1.2.0 has already been published. Skipping publish step

This means you can run the action on every push without worrying about duplicate publishes or version conflicts. You control when a new version is published by updating the version in your tile.json.

The action uses GitHub's OIDC (OpenID Connect) integration for secure, keyless authentication.

It’s worth noting that this action currently only packages the following files types in your tile: .md, .json, .js, .py, .sh, and .txt.

Here’s how to get started

Prerequisites

  1. A Tessl API token - Retrieve here, or run tessl auth token
  2. A tile with a valid tile.json manifest

Step 1: Create your tile manifest

Every tile needs a tile.json manifest file, which should look something like this:

{  
  "name": "your-workspace/your-tile-name",  
  "version": "1.0.0",  
  "summary": "What your tile does"  
}

The name must be in workspace/tile format, and version should follow semantic versioning.

Step 2: Add your Tessl API token as a secret in your GitHub settings

  1. Go to your repository's SettingsSecrets and variablesActions
  2. Click New repository secret
  3. Name: TESSL_API_TOKEN
  4. Value:

Step 3: Add the workflow file in GitHub

Create .github/workflows/publish-tile.yml:

name: Publish Tile

permissions:
  id-token: write   # Required for OIDC token
  contents: read    # Required for checkout

on:
  push:
    branches:
      - main

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: tesslio/publish@main
        with:
          token: ${{ secrets.TESSL_API_TOKEN }}

Step 4: Push and publish

Commit your changes and push to main. The action will:

  1. Check if the version already exists
  2. Create a gzipped archive of your tile files
  3. Authenticate with the Tessl API
  4. Publish your tile to the Tessl registry

Advanced usage

Publishing from a subdirectory

If your tile lives in a subdirectory (common in monorepos):

- uses: tesslio/publish@main
  with:
    token: ${{ secrets.TESSL_API_TOKEN }}
    path: './tiles/my-awesome-tile'

Multiple Tiles in One Repository

For monorepos with multiple tiles, use a matrix strategy:

jobs:
  publish:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        tile:
          - tiles/tile-one
          - tiles/tile-two
          - tiles/tile-three
    steps:
      - uses: actions/checkout@v4
      - uses: tesslio/publish@main
        with:
          token: ${{ secrets.TESSL_API_TOKEN }}
          path: ${{ matrix.tile }}

Common Errors & Fixes

The TESSL_API_TOKEN environment var is required

The action can't find your API token. Ensure:

  1. The secret is named exactly TESSL_API_TOKEN in your repository settings
  2. You're passing it correctly: token: ${{ secrets.TESSL_API_TOKEN }}

Missing or invalid tile manifest

Your tile.json is either missing or contains invalid JSON. Verify:

  1. The file exists in the tile directory
  2. It's valid JSON (use a JSON validator)
  3. If using path, ensure it points to the correct directory

Already published. Skipping the publish step

This is expected behavior when the version hasn't changed. To publish a new version, update the version field in your tile.json.

Invalid tile name. Expected format 'workspace/tile'

Your tile name must include both a workspace and tile name separated by a forward slash. Update your tile.json:

{  
  "name": "my-workspace/my-tile",  // ✓ Correct  
  "name": "my-tile"                // ✗ Missing workspace  
  "name": "my-workspace"           // ✗ Missing tile name  
}

The Takeaway

Once the above is wired in, publishing stops being a checklist.

Update tile.json, push to main, and the action publishes - or skips if nothing changed! Remember that dev who forgot to update the manifest summary? Now the workflow catches the drift before users do.

No stale files, no expired tokens, no 🫠 moments. Just tiles that stay current, automatically. Discover what's already on the Tessl Registry, or reach out in Discord if you run into issues.

Join Our Newsletter

Be the first to hear about events, news and product updates from AI Native Dev.