Skip to content

AppTown v1.0.0-rc.9

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 27 Oct 12:13
· 180 commits to main since this release
143fe27

Flokkit AppTown v1.0.0-rc.9

RC9 makes projects easier to create and rename, adds named release environments
and external sign-in, and brings operational warnings together in Attention.
It also tightens checks, credential handling and recovery of retained database
storage. Read the upgrade changes below before updating an RC7 installation.

Upgrade correction

RC8 was withdrawn because its repository-layout migration rejected historical
ended console sessions that legitimately had no checkout path. RC9 preserves
that history while retaining the checks required for live sessions and orphaned
checkouts. The upgrade regression now includes this retained RC7 state.

The changes below cover everything since RC7, the previous available release.
Take matching database and file backups before upgrading, as described in the
upgrade guide.

New and improved

  • Start with what you want to build. Project creation starts with a
    description and proposes a name and address you can change. Local repositories
    use immutable project IDs. Renaming a project keeps its previous addresses
    usable and does not rename its upstream repository or running apps. Addresses
    stay reserved even after a project is purged.
  • Name your release environments. Targets, integrations and deployments can
    have your own labels. Select a project's default release environment and use
    the same release plan and permission checks as a release to a named deployment.
    Application hostnames belong to deployments, independently of project names.
    Newly prepared Docker apps and previews receive their exact browser origin,
    removing wildcard trust of sibling projects. Portainer connections and upstream repositories are checked against
    their recorded provider identities before use.
  • External sign-in. Add one OpenID Connect provider alongside local password
    sign-in. Accounts link through stable provider subjects, not matching email
    addresses. An enabled local administrator remains available for recovery.
    This does not configure sign-in for the apps AppTown hosts. See
    external sign-in.
  • Attention. A shared page, top-bar count and Home summary show operational
    warnings for resources you can read: storage, workers, deployments and data
    protection. Missing or stale observations remain visible. Disk warnings are
    bounded on large disks and show their threshold.
  • Application health. Portainer honors declared ports, ordered initialization
    and health checks for the exact release. App Platform honors startup grace and
    expected readiness status. Maintained health observations use the declared
    execution policy and distinguish the running generation from a failed update.
  • Bounded Janitor assessment. Preview and record standing consent, then
    inspect an exact candidate for supported npm patch/minor updates, same-version
    Node base-image digest updates, supported security fixes and explicitly
    classified guidance-only adoption changes. Unsupported changes require a
    person. Automatic acceptance, landing and deployment are not available.
    Saving consent or running an assessment does not update software. See
    Janitor.
  • AppTown update preparation. Administrators can check signed release
    notifications. Linux archives include a separate managed supervisor for
    explicitly enrolled root-run systemd and local Docker installations. It keeps
    installation identity and interrupted-update startup controls outside AppTown's
    replaceable directories. Enrollment does not enable automatic replacement.
    Continue to use the documented
    upgrade procedure.
  • A revised tour. The tour follows the current project flow, demonstrates a
    plain club website becoming a bright neon version, and preserves tours at
    versioned URLs so earlier releases remain viewable.
  • Stock content ships beside release binaries as update files. Packs can name
    tool lines, and versions record their source and signer. The .NET way of
    working moves to .NET 10; the Go starter trusts configured extra certificate
    authorities. Homebrew support is available for final releases; release
    candidates do not update the formula.

Breaking changes

Upgrades and whole-AppTown restores start at RC7

The oldest supported installation and backup schema is now 167
(1.0.0-rc.7). Earlier schemas are refused before migration or restore
changes data. RC7 and RC8 installations retain their records and versions;
new installations use the complete assembled schema. RC7 archives without
database provenance remain supported. Retired migration history remains
in Git.

Root-installed archive ownership

The Linux installation instructions now keep extracted release files owned by
root, rather than the release builder. Existing archive installations should
stop the service and repair ownership of /opt/apptown (or
/opt/apptown-worker) before restarting; see the
server setup guide.
Do not change ownership of the data directory or project repositories.

Native Mac database storage

Fresh native Mac installations keep the built-in PostgreSQL database in a
Docker-managed volume. Docker Desktop's shared Mac filesystem can otherwise
change observed ownership during initialization and leave startup unable to
complete. Existing bound volumes stay in place; no data moves automatically.
The local pgdata receipt records the managed volume before PostgreSQL starts.
Missing or replaced recorded storage requires recovery. Use a whole-AppTown
backup or a database dump plus the matching data-directory copy; a directory
snapshot alone does not contain a managed database. Linux storage is unchanged.

Local repositories move to immutable project locations

Startup moves existing local repositories to project-ID directories before
application recovery. An interrupted move resumes from its journal. Unknown
ownership or surviving writers stop the upgrade for operator investigation;
AppTown does not guess which files belong to a project. -verify-only performs
this layout transition as well as schema changes. Stop writers and keep matching
database and data-directory backups before upgrading. See the
upgrade guide.

Keep the shipped update files beside the binaries

Copy share/ with bin/ when installing an archive. The daemon and worker now
read the shipped ways of working and tool versions from share/apptown/updates;
they do not start without the required files. Copying only a replacement binary
is no longer sufficient.

Confirm existing Portainer targets and addresses

Before releasing an existing Portainer deployment, an administrator must inspect
and confirm the target's provider association. Then inspect and confirm each
upgraded deployment's observed host rules and certificate domain. The upgrade
keeps the old addresses as evidence but does not treat them as verified.
These confirmations do not change the running stack or clear restore holds.
Old pending release requests without the required address snapshot need a new
release request after confirmation. See
Portainer connection identity
and deployment addresses.

Checks say "not applicable" instead of passing on nothing

A check that had nothing to judge used to pass: a Go check with no go.mod,
a frontend check with no frontend, an image scan with no image. Now each
check says what it applies to, and AppTown works out from the app contract
whether it applies before anything runs. A check that does not apply says
not applicable and why ("no part is built with go"). It is never a
pass and never an error. It does not stop anyone approving or landing, and
the change's record lists every check that was not applicable, so none is
read as passed. Once a check applies, finding nothing to judge is a
failure: the contract and the code disagree.

What changes for an existing project:

  • Landing is stricter.
    • The tests step fails when a part is built with Go, Node, Python,
      Ruby, Java, .NET or Rust and no test command is found. Before, it
      passed with "no tests found". A test command AppTown already found
      still runs, whatever the contract says.
    • The dependency scan (osv) fails when it finds no package files in an
      app whose parts are built with a language it reads. Before, it passed.
      A .NET app now commits packages.lock.json.
    • An app whose public part is a static site has image scans that say not
      applicable. Before, they passed with a note.
  • The shipped checks' scripts fail where they used to pass on a missing
    subject
    , once the check applies.
  • The app contract gains two fields, both optional:
    • tools: on a part names what it is built with, for example
      tools: [go, node]. Without it, a project's language checks, the
      dependency scan and the licence scan are not applicable.
    • notAppCode: lists folders whose code is not the app's (docs, tooling).
  • A new platform check, "the contract matches the code", reports each
    package.json, go.mod, pyproject.toml, Gemfile, Cargo.toml, pom.xml,
    .csproj, composer.json or project.godot that no part's tools: covers.
    It fails a landing that leaves a new one undescribed.
  • The check format gains appliesTo, and it is required. A check, or a
    scanner that is not manual, saved without it is refused. Checks and
    scanners already stored are given appliesTo: [repository] when the
    database migrates. That is what they meant before, so nothing stored
    behaves differently.
  • A yes given in advance has new wording. The stock landing's sentence
    is now "every check passing or not applicable". A yes given on the old
    sentence is left for a person.
  • New starters with no app yet ship their make test target commented
    out.
    The change that writes the app uncomments it.

What to do after upgrading

  1. For each project, add tools: to each part in .apptown/app.yaml, in a
    change of its own. The contract check's finding names each manifest to
    cover. Add notAppCode: for folders that are not the app's code.
  2. Give each part built with a language a test command (a Makefile test
    target, a package.json test script, go.mod or pom.xml at the root, or
    the tests step's command).
  3. Commit packages.lock.json in a .NET app
    (<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>).
  4. Run What-if on each pack's new version, then adopt it under
    Settings → Way of working.
  5. Write appliesTo on any check you author from now on.

Until a project's contract names its tools, its dependency and licence
scans say not applicable on every change. They are never shown as passed.

Invalid contract versions are refused

App contracts with a negative version now fail validation with the invalid
value named. Choose the supported version the contract is intended to use;
AppTown does not rewrite it. Omitted versions still mean version 1, explicit
versions 1 and 2 keep their existing meaning, and future versions still report
that they require a newer AppTown.

Standing Docker database needs refuse to open retained data without matching
observed engine, mount destination and volume evidence. Verified container-loss
recovery uses the bound immutable engine; unknown retained files and changed
declarations require explicit recovery. AppTown does not automatically migrate
database engines.

Backup engine provenance

Whole-AppTown backups record observed PostgreSQL server and dump-client versions.
New restores refuse malformed metadata or a recorded server major other than
PostgreSQL 16 before extracting data. Older archives without this metadata keep
the existing restore behavior; this does not add cross-major database upgrades.

Project-scope lookup failures stop authorization with an unavailable response.
They no longer become an empty group, instance scope or partial capability list.
A grant for a confirmed missing project can still be cleaned up by an instance
administrator.

Open-mode and trusted-header requests now return 503 when AppTown cannot record
the person, instead of continuing with an incomplete identity. The same refusal
applies to trusted-header OAuth consent; invalid names still return 401.

Authentication and execution failures

Unavailable credential or account lookups return 503 on the API, MCP and browser
OAuth authorization doors. They no longer appear as invalid tokens or anonymous
sessions. MCP sends no replacement-credential challenge for this failure.

Root systemd services

The daemon and worker units set DOCKER_CONFIG=/root/.docker, so boot
checks can locate Docker configuration when systemd supplies no HOME.
An operator can override the location in the service environment file.

Identity administration requires the admitted person's immutable ID. An actor
header alone no longer supplies authority to route or project membership checks.
Normal open-mode and trusted-header admission still record the person first;
receipt attribution remains separate from authorization.

Database storage and physical restore

Standing Docker databases now bind their data volumes to observed immutable engine
images, mount destinations and volume incarnations. Container loss can recover using that exact engine;
a changed declaration, replaced volume or unknown retained store refuses writable
startup. These records grant no new permission to delete data.

Whole-instance database restoration establishes new target storage before engine
startup. Physical copies require immutable source-engine evidence captured when
copied. Older physical items, including RC7 Redis RDB backups, lack that evidence
and require independently verified recovery; their archive bytes are preserved,
but automatic fill refuses. Logical copies keep their supported restore path.
A failed restore that leaves engine-data volumes requires explicit recovery before
retry; those volumes are never assumed empty. See the backup guide.

HTTP API changes

These changes are relative to RC7. The HTTP API remains experimental. The
OpenAPI description
contains the request and response definitions.

Projects, releases and storage

  • Project creation accepts automaticAddress, requestId and typed setup
    intent. Settings changes accept slug and requestId for an address change,
    with the expected settings revision. Historical addresses resolve to the
    current project; they are never reassigned.
  • GET /api/v1/projects/{slug}/repo/remote reads the upstream attachment.
    The existing POST accepts repositoryName, requestId,
    expectedAttachmentId and recoverProviderId; its response adds
    attachmentId. Attachment operations verify provider repository identity.
  • GET /api/v1/projects/{slug}/release/plan returns the typed ReleasePlan;
    GET /api/v1/projects/{slug}/targets returns ProjectTargets.
    POST /api/v1/projects/{slug}/release uses the selected default environment
    and that deployment's current authority. Its request adds defaultRevision,
    addressRevision and acceptUncheckedCopy.
  • New default-environment operations: GET and PUT /api/v1/projects/{slug}/release/default, and POST /api/v1/projects/{slug}/release/default/setup.
  • New label operations: PUT /api/v1/targets/{id}/label, PUT /api/v1/integrations/{id}/label and PUT /api/v1/projects/{slug}/deployments/{id}/label.
  • New deployment operations: PUT /api/v1/projects/{slug}/deployments/{id}/promotion-policy; GET and PUT
    /api/v1/projects/{slug}/deployments/{id}/address; and GET and POST
    /api/v1/projects/{slug}/deployments/{id}/address/observation.
  • New retained-storage operations: GET and POST /api/v1/projects/{slug}/deployments/{name}/storage-bindings. New provider
    association operations: GET and POST /api/v1/targets/{name}/provider-association.
  • GET /api/v1/tiers names the customer tier release, replacing the configured
    release deployment name (usually lan). Entries describe current standing
    deployments, with deploymentId and deploymentLabel; multiple entries can
    share a project slug. URLs and running/unknown states reflect current
    observations, and removed deployments disappear. Use release history or the
    departures view for historical releases.
  • Target settings cannot redirect a verified Portainer target to another
    endpoint by changing its environment name; attach a new target instead.
  • Deployment responses add displayLabel, requirePromotion and
    policyRevision; deployment views also include id and targetId.
    Target views add displayLabel. Backup items add engineImageID.

Sign-in, operational status and updates

  • GET /api/v1/auth/me removes can.amend and can.release (the entire can
    field). Read GET /api/v1/authz/me for current capabilities. The response
    also adds an optional external summary with displayName and allowSignup
    when external sign-in is enabled.
  • GET /api/v1/attention returns authorized conditions and observation coverage.
  • GET /api/v1/instance-updates reads release and supervisor status;
    POST /api/v1/instance-updates/check requests a release check.
  • External sign-in adds GET and PUT /api/v1/auth/external/provider,
    POST /api/v1/auth/external/test, POST /api/v1/auth/external/enabled,
    POST /api/v1/auth/external/start and GET /api/v1/auth/external/callback.
    Bindings use GET and POST /api/v1/auth/external/bindings, DELETE /api/v1/auth/external/bindings/{id} and POST /api/v1/auth/external/bindings/{id}/unlink.
  • Credential, account, identity-recording and authorization-scope lookup failures
    return unavailable responses, including HTTP 503 where described above,
    instead of proceeding anonymously or reporting invalid credentials.
    Consequential actions require an admitted principal ID and recheck retained
    credentials before queued release effects. Ambiguous need and scoped-secret
    credentials are refused; credentialed provider requests refuse redirects.

Checks and standing consent

  • Check verdicts add not-applicable; step states add not_applicable.
    Check and nonmanual scanner declarations require appliesTo as described
    above. Scanner evidence can include notApplicable explaining the result.
    Pack specifications and views add tools. Published version history adds
    source and signer; shipped stock records explicitly say when unsigned.
  • Standing consent adds GET and POST /api/v1/standing-approvals, and
    POST /api/v1/standing-approvals/preview. Each rule supports POST /api/v1/standing-approvals/{id}/assess, POST /api/v1/standing-approvals/{id}/disable and GET /api/v1/standing-approvals/{id}/history.
  • Routine publication classification adds POST /api/v1/routine-publications,
    POST /api/v1/routine-publications/preview, POST /api/v1/routine-publications/{id}/revoke and GET /api/v1/routine-publications/{kind}/{id}/history.

Deprecations

None. The RC7 upgrade floor and other compatibility changes above take effect
in this release candidate.