Skip to content

Module auto-publish #601

@BSick7

Description

@BSick7

Summary

As a Nullstone user, I want Nullstone to automatically detect when an embedded module has changed on a GitOps-tracked branch and publish a new build version — so that my infrastructure always reflects the latest committed module without any manual publishing step.


Background

When a user merges changes to a GitOps-tracked branch, Nullstone already detects changes to IaC declaration files and triggers an infrastructure sync. Embedded modules extend this behavior: Nullstone must also inspect the merge commit for changes to module paths, and if detected, publish a new build version before the IaC sync runs.

Change detection must be reliable and efficient. Two layers are used:

  1. Git diff (efficiency layer): Check whether any files under the module path appear in the merge commit diff. If not, skip the module entirely.
  2. Content hash (source of truth): Package the module and compare its hash to the last published version. Only publish if the hash differs. This handles edge cases where a diff is present but the effective content is unchanged (e.g., whitespace-only changes, reverted edits).

Acceptance Criteria

Git Diff Detection

  • On each GitOps push event, Nullstone computes the set of changed file paths from the merge commit.
  • For each declared module, Nullstone checks whether any changed path falls under the module's declared path.
  • Modules with no changed files in their path are skipped (no packaging, no hash computation, no publish).

Content Hash Comparison

  • For modules that pass the git diff check, Nullstone packages the module directory into a deterministic archive.
  • The archive's content hash is computed and compared to the hash stored for the last published build version.
  • If hashes match, the module is not republished and no version bump occurs.
  • If hashes differ, a new build version is published (see Versioning below).

Versioning

  • Build versions are published using a SHA-based pre-release scheme: 0.0.0-<short-git-sha>.
  • If the module manifest declares an explicit version:, that version is used as the base (e.g., 1.2.0-<short-sha>).
  • Build versions are not automatically promoted to any release channel.

Publish Outcome

  • On successful publish, Nullstone stores the new version ref and content hash for use by the IaC sync step.
  • Publish success and the new version are recorded in the GitOps run log.
  • On publish failure, the GitOps run is marked as failed with a clear error message identifying the module and failure reason.
  • A failed publish prevents the IaC sync from running for any workspace that references the affected module.

Force Publish

  • Users can trigger a forced republish by setting a force-publish: true flag on the module declaration in .nullstone/config.yml.
  • When force-publish: true is set, Nullstone skips the content hash comparison and always publishes on the next GitOps event.
  • Nullstone clears the force-publish flag (sets it to false) in config after a successful forced publish.
  • Users can also force publish via the CLI: ns modules publish <module-name> --force (see Story 4).

Observability

  • The GitOps run log clearly indicates for each module: skipped (no changes), skipped (hash match), or published (new version).
  • Publish failures surface in the Nullstone dashboard with the module name, error message, and a link to retry.

Technical Notes

  • The deterministic archive must produce identical hashes for identical file contents regardless of file metadata (timestamps, permissions). Standard practice: sort files by path, strip metadata before hashing.
  • The content hash and last published version ref are stored per-module-per-repo in Nullstone's backend, keyed by (org, repo, module-name).
  • The git diff check uses the merge commit's diff, not a comparison against HEAD~1, to correctly handle squash merges and force pushes.

Out of Scope

  • PR-level plan previews (referenced in the epic as a future feature).
  • Publishing on push to non-GitOps-tracked branches.
  • Promoting build versions to release channels.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions