OlammaAPI

Working with Changelogs

Each product has a changelog that tells customers what changed. Your pull requests and deploy script keep it complete; your team decides what customers see and when.

How it fits together

ChangelogOne per product, like cl_…, linked to the product’s repositories.
ChangeOne thing that changed: new, improved or fixed, for public (customers read it) or internal.
ReleaseCollects changes. There’s always one open release; a deploy ships it; a lead publishes it for customers.

What your deploy script does

  1. With each pull request, check whether it has a change. Ask by pull request; an empty list means record one.
    curl -G "https://api.olamma.sh/v1/w/your-workspace/changes" \
      -H "Authorization: Bearer $OLAMMA_KEY" \
      --data-urlencode 'product=APP' \
      --data-urlencode 'pullRequest={"repo":"acme/app","number":415}'
    const response = await fetch(`https://api.olamma.sh/v1/w/your-workspace/changes?${new URLSearchParams({"product":"APP","pullRequest":"{\"repo\":\"acme/app\",\"number\":415}"})}`, {
      headers: {
        Authorization: `Bearer ${process.env.OLAMMA_KEY}`,
      },
    });
    const data = await response.json();
    if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
    import os
    import requests
    
    response = requests.get(
        "https://api.olamma.sh/v1/w/your-workspace/changes",
        headers={"Authorization": f"Bearer {os.environ['OLAMMA_KEY']}"},
        params={"product":"APP","pullRequest":"{\"repo\":\"acme/app\",\"number\":415}"},
        timeout=30,
    )
    data = response.json()
    response.raise_for_status()
  2. Record the change in customers’ words. It joins the open release. Linking tasks adds their reporters, so they can be told when it ships.
    curl -X POST "https://api.olamma.sh/v1/w/your-workspace/changes" \
      -H "Authorization: Bearer $OLAMMA_KEY" \
      -H "Idempotency-Key: pr-acme-app-415" \
      -H "Content-Type: application/json" \
      -d '{
        "product": "APP",
        "type": "fixed",
        "audience": "public",
        "title": "Card payments work after a top-up",
        "pullRequests": [
          {
            "repo": "acme/app",
            "number": 415
          }
        ],
        "tasks": [
          "APP-12"
        ]
      }'
    const response = await fetch(`https://api.olamma.sh/v1/w/your-workspace/changes`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.OLAMMA_KEY}`,
        "Idempotency-Key": "pr-acme-app-415",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        "product": "APP",
        "type": "fixed",
        "audience": "public",
        "title": "Card payments work after a top-up",
        "pullRequests": [
          {
            "repo": "acme/app",
            "number": 415
          }
        ],
        "tasks": [
          "APP-12"
        ]
      }),
    });
    const data = await response.json();
    if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
    import os
    import requests
    
    response = requests.post(
        "https://api.olamma.sh/v1/w/your-workspace/changes",
        headers={"Authorization": f"Bearer {os.environ['OLAMMA_KEY']}", "Idempotency-Key": "pr-acme-app-415"},
        json={
            "product": "APP",
            "type": "fixed",
            "audience": "public",
            "title": "Card payments work after a top-up",
            "pullRequests": [
                {
                    "repo": "acme/app",
                    "number": 415
                }
            ],
            "tasks": [
                "APP-12"
            ]
        },
        timeout=30,
    )
    data = response.json()
    response.raise_for_status()
  3. After a production deploy, ship the release with the deployed pull requests. Their changes ship; the rest wait in a new open release.
    curl -X POST "https://api.olamma.sh/v1/w/your-workspace/releases/ship" \
      -H "Authorization: Bearer $OLAMMA_KEY" \
      -H "Idempotency-Key: deploy-a1b2c3d" \
      -H "Content-Type: application/json" \
      -d '{
        "product": "APP",
        "commit": "a1b2c3d",
        "previousCommit": "9f8e7d6",
        "pullRequests": [
          {
            "repo": "acme/app",
            "number": 415
          }
        ]
      }'
    const response = await fetch(`https://api.olamma.sh/v1/w/your-workspace/releases/ship`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.OLAMMA_KEY}`,
        "Idempotency-Key": "deploy-a1b2c3d",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        "product": "APP",
        "commit": "a1b2c3d",
        "previousCommit": "9f8e7d6",
        "pullRequests": [
          {
            "repo": "acme/app",
            "number": 415
          }
        ]
      }),
    });
    const data = await response.json();
    if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
    import os
    import requests
    
    response = requests.post(
        "https://api.olamma.sh/v1/w/your-workspace/releases/ship",
        headers={"Authorization": f"Bearer {os.environ['OLAMMA_KEY']}", "Idempotency-Key": "deploy-a1b2c3d"},
        json={
            "product": "APP",
            "commit": "a1b2c3d",
            "previousCommit": "9f8e7d6",
            "pullRequests": [
                {
                    "repo": "acme/app",
                    "number": 415
                }
            ]
        },
        timeout=30,
    )
    data = response.json()
    response.raise_for_status()
  4. Check it’s ready. Fix each problem listed, in order: record or skip pull requests without a change, and make sure customers have something to read.
    curl -G "https://api.olamma.sh/v1/w/your-workspace/releases/check" \
      -H "Authorization: Bearer $OLAMMA_KEY" \
      --data-urlencode 'product=APP'
    const response = await fetch(`https://api.olamma.sh/v1/w/your-workspace/releases/check?${new URLSearchParams({"product":"APP"})}`, {
      headers: {
        Authorization: `Bearer ${process.env.OLAMMA_KEY}`,
      },
    });
    const data = await response.json();
    if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
    import os
    import requests
    
    response = requests.get(
        "https://api.olamma.sh/v1/w/your-workspace/releases/check",
        headers={"Authorization": f"Bearer {os.environ['OLAMMA_KEY']}"},
        params={"product":"APP"},
        timeout=30,
    )
    data = response.json()
    response.raise_for_status()

Shipping on deploy is for changelogs set to release on deploy. Others release on a schedule or by hand in Olamma; List changelogs shows which.

Pull requests nobody would notice

Dependency bumps, tests and tooling don’t need a change. Skip them with a reason, so they stop counting as missing:

curl -X POST "https://api.olamma.sh/v1/w/your-workspace/releases/cr_…/skip" \
  -H "Authorization: Bearer $OLAMMA_KEY" \
  -H "Idempotency-Key: skip-acme-app-411" \
  -H "Content-Type: application/json" \
  -d '{
    "repo": "acme/app",
    "number": 411,
    "reason": "Dependency bump; nobody would notice."
  }'
const response = await fetch(`https://api.olamma.sh/v1/w/your-workspace/releases/cr_…/skip`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.OLAMMA_KEY}`,
    "Idempotency-Key": "skip-acme-app-411",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "repo": "acme/app",
    "number": 411,
    "reason": "Dependency bump; nobody would notice."
  }),
});
const data = await response.json();
if (!response.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
import os
import requests

response = requests.post(
    "https://api.olamma.sh/v1/w/your-workspace/releases/cr_…/skip",
    headers={"Authorization": f"Bearer {os.environ['OLAMMA_KEY']}", "Idempotency-Key": "skip-acme-app-411"},
    json={
        "repo": "acme/app",
        "number": 411,
        "reason": "Dependency bump; nobody would notice."
    },
    timeout=30,
)
data = response.json()
response.raise_for_status()

What stays with people

  • Publishing a release to customers is proposed through the API and approved by a lead in Olamma. A release with no headline, or nothing public, is refused until it has both.
  • Telling reporters emails the people who reported its changes. Email can’t be unsent, so a lead always approves it first.
  • Once a release is published, only its leads can change what customers read.

Write public titles in customers’ words: “Receipts load faster”, not “Cache receipt PDFs”. Refactors, alerts and infrastructure are internal.