# Shipcast v0.3.0: launch from a GitHub Action, blog in your languages, an app you can install

> Shipcast v0.3.0 drafts your launches from a GitHub Action with nothing to host, writes your blog in the languages you choose, and ships a redesigned app you can install.

- URL: https://josegarrido.dev/en/shipcast-github-action-installable-app/
- Author: José Antonio Garrido
- Published: 2026-11-03
- Language: en
- Project: [shipcast](https://github.com/yeyo11/shipcast) v0.3.0
- Tags: shipcast, github-actions, open-source, release-automation, pwa, ai
- Spanish version: https://josegarrido.dev/es/shipcast-github-action-app-instalable/

Shipcast turns a GitHub release into a launch: it reads the code at the tag, drafts the article and a post for each channel, and publishes them once you approve. Version 0.3.0 lets you run it from a GitHub Action on your own repos with nothing to host, writes your blog in the languages you choose, and brings a redesigned app you can install on your phone or desktop.

If you already run Shipcast, this post covers what changed and what to do when you upgrade.

![Shipcast's app: a release's drafts, approved and published](https://josegarrido.dev/launches/shipcast/v0.3.0/tour.gif)

## Why a GitHub Action?

Until now you needed a server to use Shipcast. That is fine for me, but it is a lot to ask of someone who only wants their next release announced. With v0.3.0 the whole flow runs in GitHub Actions: you publish a release, one drafts pull request arrives in your launches repo with the article and a post per channel, and when you merge it each channel is published once.

## How do I set up the Action?

In your project's repo, with Node 24:

```bash
npx @yeyo11/shipcast init
```

`init` writes the launch workflow that uses `yeyo11/shipcast-action@v1`, `.github/launch.yml`, and, for your launches repo, `brand.yml` plus a publish workflow. It then prints every secret you need to set. You can pass the choices up front:

```bash
npx @yeyo11/shipcast init --launches-repo you/launches --ai openai --tone "Plain, practical, first person."
```

The drafts are written with your own key. `--ai` takes `anthropic` (the default) or `openai`, and the action's `ai-base-url` input points it at any OpenAI-compatible server. To check a setup without posting anything, set the repository variable `SHIPCAST_DRY_RUN=true`: the publish run lists what it would post.

Every link to your blog goes out with `utm_source`, `utm_medium` and `utm_campaign`, so your analytics show which channel each visit came from. dev.to and Hashnode keep the clean canonical URL.

## What if GitHub's cron runs late?

Scheduled posts and retries run in a "round". GitHub delays or drops `schedule` runs, so the publish workflow has three cron lines only as a backstop and accepts `workflow_dispatch`. For rounds on time, dispatch it every 15 minutes from outside GitHub: a Cloudflare Worker, cron-job.org or your own server. `init` prints the exact call:

```bash
curl -fsS -X POST \
  -H "Authorization: Bearer $SHIPCAST_DISPATCH_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/<you>/launches/actions/workflows/shipcast-publish.yml/dispatches \
  -d '{"ref":"main"}'
```

The token is a fine-grained one for the launches repo only, with Actions read and write. A late round only delays a post; it loses none.

## How do I choose my blog's languages?

List them in `brand.yml` with any ISO 639-1 code. The first one is the primary language:

```yaml
# brand.yml
languages:
  blog: [en, es]
```

The article, the newsletter issue and the posts follow that list, and so do the language switches in the app. dev.to and Hashnode republish the English version when there is one, otherwise the first language. Watch out when upgrading: without `languages.blog`, Shipcast now writes in English only.

## What changed in the app?

Every screen was rebuilt. Launches wait for you and you approve them in the app. Each draft opens in an editor with Markdown and Visual modes, and its toolbar matches what the channel can format. Stats show each channel and each launch, a search palette jumps to any launch, account or page, and **Sync all** refreshes every account on Channels.

The app also installs. On a phone or a desktop it opens standalone, shows its own offline page when the connection drops, and offers **Reload** when a new version is out, so nothing reloads in the middle of an edit.

## How do notifications work?

Shipcast tells your phone or desktop when a reply to a comment or a launch waits for your approval, when something fails, and when a launch is out. Turn it on per device in Settings → Notifications, with a switch for each event. On iPhone, add Shipcast to the Home Screen first. A notification never shows a comment or a draft's text. On your own server, set `SHIPCAST_VAPID_PUBLIC_KEY` and `SHIPCAST_VAPID_PRIVATE_KEY` (see `docs/push.md`).

## How do I upgrade a self-hosted install?

```bash
git pull
pnpm install
pnpm app          # database migrations run on start
```

Two things to check:

- claudio now starts behind its own Compose profile: `docker compose --profile claudio up -d`, or `COMPOSE_PROFILES=claudio` in `.env`. Without either, `docker compose up -d` starts only Postgres.
- If your blog has more than English, list its languages in `languages.blog`.

## Where do I go next?

The step-by-step guide for the Action is in [docs/getting-started.md](https://github.com/yeyo11/shipcast/blob/main/docs/getting-started.md), and the full list of changes is in the [changelog](https://github.com/yeyo11/shipcast/blob/main/CHANGELOG.md). If you don't have a blog yet, [`yeyo11/shipcast-blog`](https://github.com/yeyo11/shipcast-blog) is an Astro and Tailwind template that already reads Shipcast's articles and deploys on GitHub Pages.

If Shipcast saves you writing the same announcement ten times, a star on [the repository](https://github.com/yeyo11/shipcast) helps other developers find it.
