Skip to main content

rlsbl

rlsbl

Release orchestration and project scaffolding for npm, PyPI, Go, and 14 more release targets.

Install

From PyPI:

uv tool install rlsbl

From npm (wrapper):

npm i -g rlsbl

Quick start

rlsbl scaffold          # set up CI/CD, hooks, changelog, pipelines
# ... develop, commit ...
rlsbl release init      # scaffold .rlsbl/releases/unreleased.toml
# ... edit bump type, targets, pipelines ...
rlsbl release run       # bump, tag, push, publish, create GitHub Release
rlsbl watch <sha>       # monitor CI for that release

Commands

All commands auto-detect targets (versioning) from project files (package.json, pyproject.toml, go.mod) and pipelines (publishing) from .rlsbl/config.json. Targets handle version bumps; pipelines handle where releases are published.

Command Description
check Run project checks registered via the check framework and report results
status Display the current project version, branch, last release tag, unreleased commit count, and changelog coverage. Outputs plain text by default or structured JSON with the --json flag.
scaffold Generate or update CI/CD workflows, git hooks, changelog, and license files. Safe to run repeatedly -- three-way merges template changes with your customizations. Existing files with no stored merge base are healed from their last scaffold commit before merging.
check-name Query npm, PyPI, or other registries to check whether one or more package names are available. Accepts multiple names as positional arguments and respects a configurable delay between checks.
claim-name Claim a name on a package registry by publishing a minimal placeholder package. Runs check-name first, then publishes if available.
discover Search GitHub for repositories tagged with the rlsbl topic and list them. Use --mine to filter results to only your own repositories. Requires the gh CLI to be authenticated.
watch Poll GitHub Actions CI workflow runs for a specific commit SHA and report pass or fail status. Defaults to HEAD if no SHA is provided. Useful after rlsbl release to monitor the publish pipeline.
pre-push-check Removed. This command no longer performs any check: it always exits 1 with instructions. The pre-push hook now runs rlsbl check --tag prepush instead, so a repo whose hook still calls pre-push-check needs rlsbl scaffold to regenerate it.
prs List all open pull requests for the current repository using the GitHub CLI. Shows PR number, title, author, and branch for a quick overview of pending work.
unreleased List commits between the latest release tag and HEAD, and check whether each has a corresponding changelog entry. Outputs a coverage report in plain text or JSON to help prepare the next release.
targets List all release targets detected in the current project directory, showing which ecosystems (npm, PyPI, Go, etc.) are active based on manifest files found.
deploy Run the configured deployment pipeline for the project. Supports named deploy targets and dry-run preview of what would be deployed. Branch restrictions are always enforced.
commit Commit one or more files with an Autogenerated trailer, marking the commit as machine-generated so it is automatically exempted from changelog coverage checks.
release Release orchestration commands covering the full release lifecycle. Provides 10 subcommands: run, resume, init, retry, edit, undo, deprecate, yank, scrub, reconcile.
release run Bump version, validate the JSONL changelog, run tests and lint, commit, tag, push, and create a GitHub Release. Reads the bump type (patch, minor, major, or infra) and target selection from .rlsbl/releases/unreleased.toml, which can be scaffolded with rlsbl release init. Supports dry-run preview, --approve-consequential to skip the confirmation prompt in non-interactive contexts, and --allow-dirty to skip the clean working tree check.
release resume Resume a previously failed release from where it left off. Reads the in-progress state file (.rlsbl/releases/in-progress.json, or .rlsbl-monorepo/releasables//releases/in-progress.json for releasable releases), validates that the current branch matches the saved state, and re-enters the release flow, skipping already-completed steps.
release init Scaffold a .rlsbl/releases/unreleased.toml file by auto-detecting project targets. The generated file contains a default bump type (patch), an include list of all detected targets, and per-target configuration sections for Flutter targets.
release retry Dispatch CI/CD workflows for a completed release via gh workflow run. Reads the dispatch list and ref from .rlsbl/releases/retry.toml, which is auto-scaffolded with sensible defaults if missing. Verifies the GitHub Release exists before dispatching. Each workflow in the dispatch list is triggered against the configured ref (defaults to the release tag).
release edit Sync the GitHub Release notes for a given version with the corresponding CHANGELOG.md entry. Defaults to the current version if none is specified. Use --dry-run to preview changes without updating GitHub.
release undo Revert a release. Without --version, reverts the latest release (deletes GitHub Release, removes git tag, reverts version bump commit). With --version, reverts a non-latest release if it is provably unpublished (probes registries for evidence, deletes GitHub Release + tag only, un-finalizes changelog).
release deprecate Mark a past release as deprecated. Sets the GitHub Release pre-release flag and prepends a deprecation notice to the release notes. Use --reason to explain why and --use to suggest a replacement version.
release yank Remove a published version from package registries. Probes each configured target's registry to determine publication status, then executes registry-specific removal: npm deprecate, Go retract, or PyPI manual checklist. Also marks the GitHub Release as pre-release with a yank notice.
release scrub Scrub sensitive content from git history and update release metadata to match the rewritten commits. Supports 3 modes: match (--pattern), file (--file), or recipe (--recipe). After rewriting, remaps commit hashes in JSONL changelog files, regenerates CHANGELOG.md, force-pushes, and recreates GitHub Releases on the new tags.
release reconcile Reconcile release metadata with a rewritten history: re-push the tags a rewrite moved and recreate the GitHub Releases attached to them. Reads safegit's rewrite journal (.git/safegit/rewrite-maps.jsonl) to determine what moved, so it works after ANY out-of-band rewrite, not just one driven by rlsbl release scrub. Fail-closed: a tag whose divergence from the remote the journal does not explain is a hard error, never a force-push.
changelog Structured changelog management using JSONL entries with 3 entry types (feature, fix, breaking). Add and generate CHANGELOG.md from per-commit changelog entries stored in unreleased.jsonl for precise, auditable release notes.
changelog add Append a structured changelog entry to the project's unreleased.jsonl file. Each entry includes a human-readable description, an entry type (feature, fix, or breaking), and optional commit hashes linking it to specific changes. The file is auto-committed by default. Use --no-user-facing to mark internal changes that should not appear in the published changelog.
changelog generate Compile all validated JSONL changelog entries into a formatted CHANGELOG.md file. Groups entries by type (features, fixes, breaking changes) under the appropriate version heading, preserving existing changelog content for previous releases. Use --dry-run to preview the generated Markdown output without writing to disk, which is useful for reviewing before committing.
changelog amend Append a changelog entry to a released version's JSONL file. Temporarily unlocks the read-only file, appends the entry, re-locks it, regenerates CHANGELOG.md, and syncs GitHub Release notes. Use --no-validate-hashes to skip hash validation for old or amended commits.
changelog edit Modify an existing changelog entry in unreleased or released JSONL files. Finds the entry by commit hash or entry ID, applies field changes (type, description, user-facing status), and rewrites the file atomically. For released files, temporarily unlocks the read-only file, regenerates CHANGELOG.md, and syncs GitHub Release notes.
changelog remap Remap stale commit hashes in JSONL changelog files using a mapping of old SHAs to new SHAs. Reads the mapping from a file (--map-file), the safegit rewrite journal (--from-journal), or stdin (--stdin). At least one source is required. Auto-commits with Autogenerated trailer.
monorepo Manage monorepo workspaces with multiple independently-versioned projects. Initialize workspaces, add or remove projects, sync CI workflows, check name availability, and analyze dependency graphs. Supports all 18 release targets in a single workspace.toml. Provides 19 monorepo subcommands: init, add, remove, list, sync, status, check-names, outdated, snapshot, snapshot-check, mirror, graph, impact, extract, absorb, extract-releasable, cleanup, migrate-releasable, rename-releasable. Plus 1 subgroup: release.
monorepo init Create a new monorepo workspace by generating the .rlsbl-monorepo directory and an empty workspace.toml configuration file at the current directory. This must be run at the repository root before adding individual projects with the add subcommand. Each workspace tracks multiple independently-versioned projects that share a single git repository.
monorepo add Register a project directory in the monorepo workspace.toml configuration. The path argument specifies the project's location relative to the repo root. Supports 6 optional settings: display name, target registry, glob patterns for change detection, subtree remote URL, inter-project dependencies, and a library flag to mark shared code packages.
monorepo remove Unregister a project from the monorepo workspace.toml by its path. This removes the project entry from the workspace configuration file but does not delete any files, directories, or git history on disk. The project's code remains intact and can be re-added later with the add subcommand if needed.
monorepo list Display all projects registered in the monorepo workspace.toml file. For each project, shows the project name, relative path from the repo root, target registry for publishing, and any configured options such as watch patterns, subtree remotes, inter-project dependencies, and whether the project is marked as a library.
monorepo sync Inline every project's CI jobs into a single generated ci-router.yml (and publish jobs into publish.yml) in the shared .github/workflows directory at the repository root. Jobs are inlined rather than routed via reusable-workflow calls because GitHub rejects workflows that reference 20 or more reusable workflows. Stale per-project workflow copies at the root are removed via saferm.
monorepo status Show the current version, last release tag, and changelog coverage for every project in the monorepo workspace. Coverage is the real JSONL figure -- the commits since the project's last tag, scoped to the project and minus the exempt ones, rendered covered/tracked with an (N exempted) suffix, or 'no changelog' when the project has no changes directory. Provides a quick overview of which projects have pending changes and are ready for their next release.
monorepo check-names Check package name availability on a target registry for all projects in the monorepo workspace. Queries the registry API for each project name and reports whether it is available or already taken. Supports optional prefix and suffix arguments to test naming conventions like scoped packages, with a configurable delay between registry queries to avoid rate limiting.
monorepo outdated Scan all projects in the monorepo workspace for intra-workspace dependencies that reference older versions than what is currently available in the workspace. Lists each outdated dependency with the referenced version and the latest available version, helping identify which downstream projects need a version bump after upstream releases.
monorepo snapshot Regenerate the committed JSON artifact at .rlsbl-monorepo/snapshot.json summarizing all packages, versions, dependencies, and graph structure, and commit it. Verifying without regenerating is a separate command, rlsbl monorepo snapshot-check. Under --dry-run the artifact is computed but neither written nor committed, and the preview names both steps.
monorepo snapshot-check Verify that .rlsbl-monorepo/snapshot.json matches the workspace it describes, without regenerating it. Exits 1 when the artifact is stale or missing. This is the read-only half of the former monorepo snapshot --check flag; rlsbl monorepo snapshot is the half that writes.
monorepo mirror Reconcile a monorepo project's subtree mirror toward its desired state. The mirror is a tool-owned, derived artifact: it observes the remote, then converges it to exactly one scaffold commit atop the current deterministic subtree split, force-pushing (with lease) as the routine write. A tripwire refuses to touch a mirror carrying foreign (hand-authored) commits. Use --dry-run to print a plan (converged, behind, scaffold-missing, contract-violated, or virgin) without writing.
monorepo graph Export the monorepo dependency graph as DOT (Graphviz) or an indented text tree; the framework-owned --json yields the same graph as a structured document. Supports filtering by a root package (transitive deps) or reverse package (transitive rdeps), with optional depth limiting. Use --output to write the rendering to a file instead of stdout.
monorepo impact Analyze the impact of changes to a package, file, or git diff range on the monorepo dependency graph. Shows direct and transitive dependents, test scope, and release candidates as a human report, or as a structured document under the framework-owned --json. Supports package names, file paths, and --since for git-based change detection.
monorepo extract Extract a package from the monorepo into a new standalone repository. Clones the monorepo, runs git filter-repo to keep only the package's history, migrates changelog entries, creates .rlsbl/ config in the new repo, and removes the project from workspace.toml.
monorepo absorb Absorb an external repository as a package in the monorepo. Rewrites the source's history to live under the destination path, fetch-merges it (preserving full history with rewritten paths), imports its version tags under the monorepo tag scheme, and remaps its JSONL changelog hashes to the new commits.
monorepo extract-releasable Extract all member packages of a releasable into a new repository. If the releasable has one member, creates a single-project repo. If it has multiple members, creates a new monorepo with workspace.toml. Migrates changelog entries for each member and removes all extracted projects from the source workspace.
monorepo cleanup Remove per-package release-state residue from releasable member packages: .rlsbl/changes/, .rlsbl/releases/, .rlsbl/bases/, .rlsbl/lint/, .rlsbl/version, per-package CHANGELOG.md, and .rlsbl/config.json when identical to the releasable-level config. Per-package hooks/ directories are preserved (live feature), and members whose path is the workspace root are exempt. Deletions go through saferm (audit trail, recoverable) and are committed automatically. Requires an explicit-mode workspace ([[releasables]] in workspace.toml). Detect residue first with rlsbl check --name releasable-residue.
monorepo migrate-releasable Migrate a releasable from per-package release state to the releasable model. Detects current state, consolidates per-package changelogs and versions into the releasable directory, creates a releasable-format migration tag, and removes orphaned per-package .rlsbl/changes/ and .rlsbl/releases/ directories. Requires the workspace to be in explicit mode (with [[releasables]] in workspace.toml).
monorepo rename-releasable Rename a releasable group. Rewrites the [[releasables]] name and every member's releasable field in workspace.toml (preserving comments), moves the state directory, drops the stale changelog validation cache, re-runs monorepo sync, and commits it all as one commit. When tag_format contains {name}, a boundary alias tag for the current version is created at the old tag's commit and pushed; historical releases stay under the old prefix. Idempotent: re-running heals a crash between the commit and the tag push.
dev Developer utilities for locally working with rlsbl projects, including editable installs that mirror the project's release target (pypi -> uv tool install -e, npm -> npm link, go -> go install).
dev install Install the project locally for development by running each detected target's own install command. --global (the default) is supported by 7 targets: pypi (uv tool install -e), npm (npm link), go, deno, zig, swift, and hex. --venv installs into the project's local environment instead and covers pypi, npm, deno, and hex; other targets are skipped with a reason. --uninstall reverses a previous install on pypi, npm, and deno. In monorepo mode, pair with --all, --include, or --exclude.
dev sync Overlay local editable checkouts of sibling projects onto this project's locked environment. Reads dev-sources.toml.local-only for overlay entries, runs uv sync --inexact excluding overlaid packages, then uv pip install -e per entry. Requires UV_NO_SYNC=1 in the environment to prevent bare uv run from reverting overlays.
dev status Report the state of local dev-sync overlays: for each package recorded in the dev-overlays sentinel, show its declared editable checkout path and version alongside the venv's actual install (editable at the expected path, WIPED back to a registry wheel, or missing entirely). Exits 1 if any overlay drifted so scripts and pre-run guards can detect a silent wipe by a bare uv sync or uv run; exits 0 when all overlays are intact or none are declared.

Global flags: --help, --version, --dry-run, --approve-consequential, --quiet, --verbose.

Release flow

When you run rlsbl release run:

  1. Reads .rlsbl/releases/unreleased.toml for bump type (patch/minor/major) and target selection
  2. Verifies gh CLI is installed and authenticated
  3. Checks working tree is clean (use --allow-dirty to override)
  4. Fetches origin and verifies local branch is not behind remote
  5. Reads the current version from the primary project file
  6. Computes the new version; confirms the tag does not already exist
  7. Validates JSONL changelog via the check system
  8. Runs .rlsbl/hooks/pre-checks.sh if present (user-owned, non-zero aborts)
  9. Runs built-in tests and lint
  10. Runs .rlsbl/hooks/pre-release.sh if present (scaffold-managed, non-zero aborts)
  11. Acquires advisory lockfile (.rlsbl/lock) to prevent concurrent operations
  12. Writes the new version to all detected project files and .rlsbl/version
  13. Commits the version bump (uses safegit if available)
  14. Tags and pushes to origin
  15. Finalizes JSONL changelog (renames unreleased.jsonl, generates CHANGELOG.md)
  16. Creates a GitHub Release with the changelog entry as notes
  17. Runs publish pipelines (configured in .rlsbl/config.json under pipelines)
  18. Runs .rlsbl/hooks/post-release.sh if present (non-fatal)
  19. Prints Watch CI: rlsbl watch <sha>

Use --dry-run to preview without changes: mutating operations are recorded and printed as a would-do log rather than performed. A small set of commands declares itself consequential (release run/resume/retry/undo/deprecate/yank/scrub/reconcile, claim-name, deploy, monorepo release run/mirror/absorb/extract/extract-releasable) and asks for confirmation before running; pass --approve-consequential in non-interactive contexts (CI, AI agents), where the prompt is a hard error instead. Every other command runs without asking.

Create the release file with rlsbl release init, which auto-detects project targets and scaffolds the TOML file.

First release: if the current version has never been tagged, release publishes it as-is (bump type is ignored).

Pre-release versions (e.g. 1.0.0-beta.1) are supported.

Scaffold

rlsbl scaffold              # create or update CI/CD for all detected registries
rlsbl scaffold --force      # overwrite managed files (user-owned files still preserved)
rlsbl scaffold --no-auto-commit  # skip auto-commit of scaffolded files

Created files are committed automatically by default.

File Purpose
.github/workflows/ci.yml CI workflow (lint, test)
.github/workflows/publish.yml Publish on GitHub Release (OIDC)
CHANGELOG.md Version changelog
LICENSE MIT license (author and year filled in)
.gitignore Standard ignores for the ecosystem
CLAUDE.md AI assistant instructions
.claude/settings.json Claude Code settings
.rlsbl/hooks/pre-checks.sh User-customizable pre-checks validation
.rlsbl/hooks/pre-release.sh User-customizable pre-release validation
.rlsbl/hooks/post-release.sh User-customizable post-release actions
.git/hooks/pre-push Captures push refs, runs rlsbl check --tag prepush
.rlsbl/bases/ Three-way merge bases for scaffold

Three-way merge: Bases are stored at scaffold time. On re-run, user customizations and template updates merge via git merge-file. Conflicts get git-style conflict markers.

User-owned files (CHANGELOG.md, LICENSE, hooks) are never overwritten, even with --force.

Customizing CI without conflicts: Instead of editing ci.yml or publish.yml (which can produce merge conflicts on re-scaffold), put extra jobs in a separate workflow file scaffold never touches:

  • .github/workflows/ci-custom.yml -- runs alongside ci.yml
  • .github/workflows/publish-custom.yml -- runs alongside publish.yml

See docs/ci-customization.md for an example.

Runs config migrations when .rlsbl/config-schema.json exists.

Check system

rlsbl includes 76 checks across 9 tags.

Tag Checks Description
project 14 Version, name, license, description consistency; config schema; stale private hook; publish-mode workflow; npm mismatch; target/dunder version readability; selfdoc drift; scaffold conflicts
release 5 Local/remote tag, GitHub Release, branch sync, scaffold conflicts
changelog 9 Hash resolution, range, coverage, orphans, schema, user-facing, batch limits, entry
workspace 14 CI router, CI sync, targets, unregistered, stale entries, dev-only/unversioned boundaries, dead packages, subtree remote, buildability, gitignore, root conflict, Go companion tags, workspace tests
quality 9 Dead modules, circular deps, library/ruff lint, deps runtime-test-only/dev-in-lib, scaffold vars, test suite, Maven Central metadata
prepush 6 Changelog coverage, gitignore guard, manual-push warning, tests, scaffold conflicts
(untagged) 4 Layers violations, deps unused/undeclared/stale
rlsbl check --all              # run all checks
rlsbl check --tag changelog    # run checks by tag
rlsbl check --name lock        # run a single check

Undo

rlsbl release undo                          # interactive: confirms once, then auto-pushes
rlsbl release undo --approve-consequential  # non-interactive: skips the confirmation

Reverts the last release:

  1. Deletes the GitHub Release
  2. Deletes the git tag (remote + local)
  3. Reverts the version bump commit (if HEAD matches the tag)
  4. Pushes the revert commit (the single confirmation covers the whole rollback)

On partial failure, prints a structured summary table with remediation commands for each failed step.

Pre-push hook

The .git/hooks/pre-push hook captures push refs from git and runs rlsbl check --tag prepush, which enforces:

  1. Changelog coverage -- every pushed commit must have a JSONL entry
  2. Gitignore guard -- rlsbl-managed files must not be gitignored
  3. Manual push guard -- hard error when pushing to a release branch outside rlsbl release
  4. Test suite -- runs project tests (single-project) or affected project tests (monorepo)

The hook is namespace-aware: it enforces on refs/heads/* and exits 0 for refs/tags/* (release tags, pushed by rlsbl itself) and refs/backups/* (tool-owned backup slots). Release-internal pushes run git push --no-verify and never invoke the hook, so there is no environment-variable bypass to leak.

Old hooks that call rlsbl pre-push-check no longer work: the command was removed and now exits non-zero with an error, which blocks the push. Run rlsbl scaffold to install the current hook.

To reinstall, run rlsbl scaffold -- it writes the current hook (and upgrades any previously shipped version in place).

Ecosystem tagging

scaffold and release add an "rlsbl" keyword to project manifests and set the rlsbl topic on the GitHub repository, making projects discoverable via rlsbl discover.

To disable:

Method Scope
--no-tag flag Single invocation
{"tag": false} in .rlsbl/config.json This project
{"tag": false} in ~/.rlsbl/config.json All projects

Monorepo

Manage multi-package workspaces with rlsbl monorepo:

  • monorepo init / monorepo add / monorepo remove -- workspace management
  • monorepo sync -- synchronize CI workflows
  • monorepo graph -- export dependency graph (DOT, text, or --json payload)
  • monorepo snapshot -- committed JSON artifact of workspace state
  • monorepo impact -- change analysis across the dependency graph
  • monorepo release run -- batch release in topological order

Supports architectural layer rules via [layers] in workspace.toml for enforcing dependency direction.

Environment variables

Variable Default Description
RLSBL_VERSION -- Set when running pre-release and post-release hooks; contains the version being released
RLSBL_DIST_DIR -- Set when running custom_assets build commands; points to the distribution directory for output files
GITHUB_TOKEN -- Used by gh CLI for GitHub API calls; discover works unauthenticated for public repos

First publish

Registry Setup Then
npm Add NPM_TOKEN secret to GitHub repo (Settings > Secrets > Actions) CI publishes on GitHub Release
PyPI Set up Trusted Publishing (OIDC, no tokens needed) CI publishes via OIDC
Go Push tag -- Go modules are published by the tag itself pkg.go.dev indexes automatically

Requirements

  • Python 3.11+
  • GitHub CLI (gh), installed and authenticated
  • git
  • Node 24+ (for npm CI/publish templates)

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rlsbl-0.114.0.tar.gz (2.8 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rlsbl-0.114.0-py3-none-any.whl (828.8 kB view details)

Uploaded Python 3

File details

Details for the file rlsbl-0.114.0.tar.gz.

File metadata

  • Download URL: rlsbl-0.114.0.tar.gz
  • Upload date:
  • Size: 2.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for rlsbl-0.114.0.tar.gz
Algorithm Hash digest
SHA256 3e567d8ca421ac9a8d6dc8f2142d8f951a7ca09fe7a5e04743317d11fc08c2a3
MD5 b74d7f55b59d06792134e31b1a4540ed
BLAKE2b-256 82fbeb748c641d84da7a2c864fcabc3d1ad55fb36fbc9a2aaa80644f7131da2e

See more details on using hashes here.

Provenance

The following attestation bundles were made for rlsbl-0.114.0.tar.gz:

Publisher: publish.yml on smm-h/rlsbl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rlsbl-0.114.0-py3-none-any.whl.

File metadata

  • Download URL: rlsbl-0.114.0-py3-none-any.whl
  • Upload date:
  • Size: 828.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for rlsbl-0.114.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9202458f49b32148ff4c34542e70fca7cb76ea9a90e9d968241e620dcec39443
MD5 a5496d0931a79bb76773b08ec8cb0e72
BLAKE2b-256 1db0eca2f607f33e7b498e4673f7ed686430511a38b8c83d7af1335638147ea8

See more details on using hashes here.

Provenance

The following attestation bundles were made for rlsbl-0.114.0-py3-none-any.whl:

Publisher: publish.yml on smm-h/rlsbl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page