# Make your first release

Initialize a small repository, record a change, review affected packages, update versions, and publish.

Source: https://semifold.noctisynth.org/docs/getting-started/first-release/
Language: en



This tutorial follows the normal interactive CLI. You will create Semifold configuration, record one changeset, inspect the packages affected by it, update files, and prepare a registry publish.

## Before you start [#before-you-start]

Use a Git repository whose default branch is `main` and whose worktree is clean. The example assumes at least one valid Rust package with a `Cargo.toml`; the same lifecycle applies to other built-in ecosystems.

Install Semifold first if `smif --version` does not work. The [installation guide](https://semifold.noctisynth.org/docs/getting-started/installation/) lists every supported method.

## 1. Initialize the repository [#1-initialize-the-repository]

Run this from the repository root:

```bash
smif init
```

The prompts guide you through:

1. which package ecosystems to discover;
2. the base and release branch names;
3. default changelog categories;
4. whether to generate GitHub Actions workflows.

For this tutorial, select Rust, keep `main` and `release`, accept the default categories, and generate the workflows.

<ExpectedOutput title="Files created">
  <Files>
    <Folder name=".changes">
      <File name="config.toml" />
    </Folder>

    <Folder name=".github">
      <Folder name="workflows">
        <File name="semifold-ci.yaml" />

        <File name="semifold-status.yaml" />
      </Folder>
    </Folder>
  </Files>
</ExpectedOutput>

Open `.changes/config.toml`. Under `[packages]`, confirm that each discovered package has the expected path and resolver. The table key is its stable `PackageId`, which may differ from the manifest's registry name.

If this repository was already initialized and packages later changed, use `smif config sync` instead of running `init --force` again.

### Configure GitHub Actions permissions [#configure-github-actions-permissions]

Before running the generated workflows, open the repository's **Settings → Actions → General → Workflow permissions**, then:

1. Select **Read and write permissions** so the release workflow can push prepared version commits.
2. Enable **Allow GitHub Actions to create and approve pull requests** so it can create or update the release pull request.

Save the settings before continuing. Organization or enterprise policy can prevent these repository-level options from being enabled; in that case, ask an administrator to allow them at the higher level. See GitHub's [repository Actions settings documentation](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository).

## 2. Make one user-visible change [#2-make-one-user-visible-change]

Change a public API or another behavior that users will notice. Keep the change small enough that its version impact is easy to judge.

Now record the release intent:

```bash
smif commit
```

Choose the changed package, select `patch`, `minor`, or `major`, choose a changelog category, give the changeset a short name such as `add-api`, and write a user-facing summary.

Semifold creates a file like:

```md title=".changes/add-api.md"
---
my-package: "minor:feat"
---

Add the public API.
```

`minor` requests the version increase. `feat` chooses the changelog section; it does not select a release channel.

Commit the changeset with the code change so reviewers can evaluate both together.

## 3. Review affected packages [#3-review-affected-packages]

```bash
smif status
```

<ExpectedOutput title="What to verify">
  * your package appears with the expected current and target versions;
  * its direct reason points to the changeset file named `.changes/add-api.md`;
  * any additional package has an understandable dependency-propagation reason;
  * the final message says the release plan is ready, not that files were changed.
</ExpectedOutput>

If a package or version is wrong, stop here. Correct the changeset, package ID, or dependency configuration and run `smif status` again.

## 4. Choose the automated or manual path [#4-choose-the-automated-or-manual-path]

If `smif init` generated the GitHub Actions workflows, the recommended path stops using local release commands here:

1. push the code change and `.changes/add-api.md`, then merge that pull request into `main`;
2. the generated workflow runs `smif ci`, updates the configured `release` branch, and creates or refreshes its release pull request;
3. review the generated versions and changelogs in that release pull request, then merge it into `main`;
4. the next workflow run sees no pending changesets and publishes the prepared package versions in dependency order.

Do not also run `smif version` or `smif publish` locally for the same release. Continue below only when the repository does not use the generated workflow, or when you are deliberately learning and testing the manual mechanism in a disposable repository.

## 5. Manually preview and apply version changes [#5-manually-preview-and-apply-version-changes]

Preview the file and command work first:

```bash
smif version --dry-run
```

The preview does not apply normal version side effects. A configured command runs during the preview only when its configuration explicitly says `dry-run = true`; such a command must be safe to run repeatedly.

When the preview matches your intent, apply it:

```bash
smif version
```

Semifold updates package versions and eligible internal requirements, writes changelogs, runs configured post-version work, and consumes applied changesets.

Review the Git diff and run the repository's normal tests. Commit these generated files to the `release` branch, or let the generated GitHub Actions workflow maintain the release pull request.

## 6. Manually publish [#6-manually-publish]

After the version changes reach the branch used for publishing, provide the registry credentials required by the selected ecosystems.

Preview the publish run:

```bash
smif publish --dry-run
```

This validates package ordering and runs read-only registry pre-checks without publishing packages or creating Forge releases.

When the preview is correct:

```bash
smif publish
```

Packages publish in dependency order. The final report distinguishes successful, skipped, failed, and not-started packages. In CI, add `--github-release` when the configured GitHub Releases and assets should also be created.

## If something fails [#if-something-fails]

* <strong>Package not found:</strong> use the `PackageId` key from `[packages]` in `.changes/config.toml`, not a guessed registry name.
* <strong>Worktree is dirty:</strong> inspect and commit unrelated files first. `--allow-dirty` means you deliberately accept the current diff as input; it does not clean the repository.
* <strong>Registry version already exists:</strong> Semifold skips that registry command. When GitHub Releases are enabled, it may still create a missing release; an existing release does not trigger asset recovery.
* <strong>Publish partially fails:</strong> use the final successful, failed, and not-started states to repair the failing credential, pre-check, or command before retrying. Do not manually republish a version confirmed to exist.

## Automation after the workflow is clear [#automation-after-the-workflow-is-clear]

Interactive prompts are the normal learning and local-maintenance path. CI systems and constrained environments can provide the same answers as flags:

```bash
smif init --resolvers rust \
  --base-branch main \
  --release-branch release \
  --default-tags \
  --github-actions

smif commit --name add-api \
  --package my-package=minor \
  --tag feat \
  --summary "Add the public API."
```

These flags are an automation compatibility surface, not a different release model.

You now have the complete basic lifecycle: discover packages, record a changeset, update related versions and changelogs, and publish in dependency order. Continue with the [configuration overview](https://semifold.noctisynth.org/docs/configuration/overview/) when the repository needs more policy.

