BASIC

GitHub

Keep your plugin or theme on GitHub and let every tagged release become the new version on your Hoster site. A GitHub Actions workflow builds the zip and publishes a GitHub release. Hoster reads the release and hands it to your customers.

How it works

  • Hoster reads the latest release of the linked repository and takes its first .zip asset. Pre-releases and drafts are skipped.
  • The release tag becomes the Download's version; a leading v is removed.
  • Public repository: the Download URL is the release asset on GitHub, and Hoster passes the file through when a client downloads it.
  • Private repository: Hoster downloads the asset with your connected GitHub account. It rebuilds the zip with a top-level folder named after the Download's slug and keeps it in private storage. Private repositories need a connected GitHub account (see below).

Hoster syncs the release when you save the Download, and on its own when you add the release webhook (see below).

Step 1: Create the repository

  1. Create a new repository on GitHub and give it a name.
  2. Choose Public (everyone can see it) or Private (only you and the people you invite).

Create a repository

Repository settings

For a block plugin you can start from the official scaffold, for example:

npx @wordpress/create-block@latest my-block

Step 2: Add the Hoster files

  1. Create the Download on your Hoster site (see Create Plugin Update).
  2. Go to Downloads → Resources and choose it.
  3. Add the files from the Main plugin File and Updater tabs (and License for a licensed product).
  4. Add the three files from the GitHub Release tab:
my-plugin/
├── my-plugin.php
├── inc/
│   ├── hoster.php
│   └── update.php
├── .github/
│   └── workflows/
│       └── release.yml
├── .distignore
└── .gitignore
  • .gitignore keeps node_modules/, vendor/, build/, dist/ and .DS_Store files out of the repository.
  • .distignore keeps development files out of the release zip: node_modules/, src/, .git/, .github/, .gitignore, package.json, package-lock.json, the readme files and .distignore itself. Edit it to match your project.
  • release.yml is the GitHub Actions workflow that builds the release.
Tip
Ignored files stay on your computer but never reach the repository. This keeps the repository small and its history clean.

Step 3: What the release workflow does

The workflow runs when you push a version tag. It:

  1. Checks out the repository.
  2. Runs npm install and npm run build when the repository has a package.json.
  3. Runs composer install --no-dev --optimize-autoloader when it has a composer.json, so vendor/ ends up in the zip without being in the repository.
  4. Copies the files to dist/, leaving out everything listed in .distignore.
  5. Zips them as <download-slug>.zip.
  6. Creates a GitHub release for the tag with the zip attached.

It runs for tags made of numbers and dots, like 1, 1.2 or 1.2.0, and for pre-release tags like 1.2.0-beta.1 or 1.2.0-rc.3. The same tags with a leading v work too, like v1.2.0 or v1.2.0-beta.1: Hoster removes the v from the version. A tag with a - becomes a GitHub pre-release, which Hoster ignores: use it to test builds before you ship them.

Tip
The tag must match the Version: header in your code, apart from the v. A release.yml copied from Hoster 1.3 or older only runs for tags without the v; copy the file from the GitHub Release tab again to get both.

Step 4: Give the workflow a token

The generated release.yml creates the release with a repository secret called YOUR_GITHUB_TOKEN:

env:
  GITHUB_TOKEN: ${{ secrets.YOUR_GITHUB_TOKEN }}

Create that secret, or change the name in the file to a secret you already have.

Create a personal access token

  1. Open https://github.com/settings/tokens.
  2. Generate a new token that can write to the repository's contents: a classic token with the repo scope, or a fine-grained token for this repository with Contents: Read and write.
  3. Copy the token.

Personal access tokens

Add it to the repository

  1. In the repository, open Settings → Secrets and variables → Actions.

Secrets and variables

  1. Click New repository secret.

New repository secret

  1. Name it YOUR_GITHUB_TOKEN (or the name you use in release.yml), paste the token and save.

Add the secret

Tip
You can use GitHub's built-in token instead. Change the line to secrets.GITHUB_TOKEN and give the workflow write access, with permissions: contents: write in release.yml or under the repository's Settings → Actions → General → Workflow permissions.

Step 5: Release a version

  1. Change the Version: header in your code, for example to 1.2.0, and commit.
  2. Create a tag with the same version and push it:
git tag 1.2.0
git push origin 1.2.0

The workflow builds the zip and creates the release. Follow it in the repository's Actions tab.

Step 6: Link the Download to the repository

  1. Open the Download and turn on GitHub Repository in the sidebar.
  2. With a connected GitHub account, choose the repository from Select a GitHub Repository; the owner fills in on its own. Without one, type the GitHub owner and the Repository name.
  3. Click Update.

Hoster reads the latest release and fills in the Download URL and Version. Both fields are read-only while the Download is linked to GitHub. Upload new version and the Release API are not available for these Downloads.

GitHub toggle

GitHub fields

Repository fields

Synced version

Without the webhook, Hoster only checks GitHub when you save the Download: after each release, open the Download and click Update.

Release webhook

The webhook tells your Hoster site about each new release, so the linked Downloads update on their own. Find the values under Downloads → GitHub Settings → Release webhook:

  • Payload URL: https://your-site.com/wp-json/hoster/v1/github-webhook
  • Content type: application/json
  • Secret: generated for your site
  • Events: Releases

Set it up on GitHub:

  1. In the repository, open Settings → Webhooks → Add webhook.
  2. Paste the Payload URL and the Secret, and set Content type to application/json.
  3. Choose Let me select individual events, tick only Releases, and click Add webhook.

GitHub sends a test ping right away; Hoster answers it, so the webhook shows a green check.

What happens on a release:

  • A published or edited release updates every Download linked to that repository (published, draft or private Downloads). Pre-releases and drafts are ignored.
  • The workflow sometimes publishes the release before the zip is attached. Hoster then tries again after 1, 3 and 10 minutes (this uses WP-Cron).
  • Requests without the right secret are refused.

Regenerate Secret creates a new secret. The webhook on GitHub stops working until you paste the new secret there too.

The webhook works for public repositories without a connected account. Private repositories need the connected account to download the zip.

Connect your GitHub account

Connecting your GitHub account gives you two things:

  • Hoster can read releases of your private repositories.
  • You choose the repository from a list instead of typing the owner and name.

Not connected

Not connected

Connected

Connected

Create a GitHub OAuth App

  1. Go to Downloads → GitHub Settings and click Get Help: it shows the values below for your site.
  2. Open https://github.com/settings/applications/new.
  3. Application name: anything that helps you find it later.
  4. Homepage URL: your website's URL.
  5. Application description: optional.
  6. Authorization callback URL (Hoster's help calls it Redirect URI): the URL shown in Hoster, which looks like this:
https://your-site.com/wp-admin/edit.php?post_type=downloads&page=github-settings&oauth_callback=1
  1. Leave Device Flow off. Expire user access tokens can stay on: Hoster refreshes the tokens on its own.
  2. Click Register application.
  3. Copy the Client ID and generate a Client secret.

Connect

  1. Paste the Client ID and Client Secret in Downloads → GitHub Settings.
  2. Click Connect Account.
  3. GitHub asks you to authorize the app; accept.

You come back to Hoster, which shows your GitHub account name and is connected. Disconnect Account removes the connection and the saved app details.

When the connection expires

Hoster refreshes the GitHub token before it expires. If GitHub refuses the refresh (for example after you revoked the app), Hoster shows "Hoster: the GitHub connection has expired, so releases are no longer synced from GitHub." on the Downloads screens, the Dashboard and in the Download editor. Click Reconnect GitHub and connect again.