{"id":46869010,"url":"https://github.com/yehezkieldio/firefly","last_synced_at":"2026-03-10T19:31:00.239Z","repository":{"id":288924546,"uuid":"968548203","full_name":"yehezkieldio/firefly","owner":"yehezkieldio","description":"CLI orchestrator for automatic semantic versioning, changelog generation, and creating releases. Built for my own use cases.","archived":false,"fork":false,"pushed_at":"2026-01-19T12:54:03.000Z","size":2533,"stargazers_count":10,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"v3","last_synced_at":"2026-01-19T18:30:19.334Z","etag":null,"topics":["bun","changelog","conventional-commits","semver"],"latest_commit_sha":null,"homepage":"https://npmjs.com/package/fireflyy","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yehezkieldio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":"yehezkieldio","buy_me_a_coffee":"yehezkieldio","custom":["https://www.nihbuatjajan.com/yehezkieldio"]}},"created_at":"2025-04-18T09:26:45.000Z","updated_at":"2026-01-19T12:53:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"651eef2e-f1d1-4c77-a331-b021133b32af","html_url":"https://github.com/yehezkieldio/firefly","commit_stats":null,"previous_names":["yehezkieldio/artemis","yehezkieldio/firefly"],"tags_count":75,"template":false,"template_full_name":null,"purl":"pkg:github/yehezkieldio/firefly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yehezkieldio%2Ffirefly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yehezkieldio%2Ffirefly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yehezkieldio%2Ffirefly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yehezkieldio%2Ffirefly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yehezkieldio","download_url":"https://codeload.github.com/yehezkieldio/firefly/tar.gz/refs/heads/v3","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yehezkieldio%2Ffirefly/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30350019,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T15:55:29.454Z","status":"ssl_error","status_checked_at":"2026-03-10T15:54:58.440Z","response_time":106,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bun","changelog","conventional-commits","semver"],"created_at":"2026-03-10T19:30:59.559Z","updated_at":"2026-03-10T19:31:00.227Z","avatar_url":"https://github.com/yehezkieldio.png","language":"TypeScript","funding_links":["https://github.com/sponsors/yehezkieldio","https://buymeacoffee.com/yehezkieldio","https://www.nihbuatjajan.com/yehezkieldio"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"left\"\u003e\n\n\u003ch3\u003eFirefly\u003c/h3\u003e\n\u003cp\u003eAutomatic semantic versioning, changelog generation, and creating GitHub releases via a CLI.\u003c/p\u003e\n\n\u003c/div\u003e\n\n---\n\nFirefly is a Command Line Interface (CLI) tool designed to streamline and automate the entire release process of semantic versioning, changelog generation, and a GitHub release, ensuring consistent and efficient steps for me and possibly for you too. It is built on the principles of [Semantic Versioning](https://semver.org/) and [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) to deliver predictable versioning and clear, structured commit history for any project.\n\n**How It Works:**\n\n- Runs preflight checks to ensure a safe environment\n- Determines the next version automatically from commit history or via manual selection\n- Bumps the version in `package.json`\n- Generates changelogs with [git-cliff](https://github.com/orhun/git-cliff)\n- Commits the changes and creates a Git tag\n- Pushes the changes to the remote repository\n- Creates a GitHub release with the generated changelog via GitHub CLI\n\n## Getting Started\n\n#### Prerequisites\n\nFirefly requires [Bun](https://bun.sh/) and the [GitHub CLI](https://cli.github.com/) installed and authenticated.\n\n\n#### Per-Project Installation\n\nFor project-specific installations, add Firefly as a development dependency:\n\n```bash\nbun add -D fireflyy\n```\n\n#### Global Installation\n\nFor system-wide access across multiple projects:\n\n```bash\nbun install -g fireflyy\n```\n\n### Usage\n\n#### The release Command\n\nFirefly consolidates the entire release steps into a single command that orchestrates version bumping, changelog generation, and GitHub release creation.\n\n```bash\nfirefly release\n```\n\n#### Inference and Overrides\n\nBy default, Firefly intelligently infers project details from your environment:\n\n- **Project name**: Extracted from `package.json` name field\n- **Repository**: Detected from Git remote origin URL\n- **Changelog path**: Defaults to `CHANGELOG.md` in the project root\n- **Current version**: Read from `package.json` version field\n- **Scope**: Automatically parsed from scoped package names\n- **Branch**: Current Git branch\n\nThese inferred values provide sensible defaults but can be overridden through CLI flags or from the configuration file.\n\n#### Command Line Options Reference\n\n```bash\nUsage: firefly release [options]\n\nBump a new version, generate a changelog, and publish the release.\n\nOptions:\n  --ci                                   Run in CI environment.\n  --repository \u003crepository\u003e              Repo in 'owner/repo' format, auto-detected if omitted. (default: \"\")\n  --verbose                              Enable verbose logging.\n  --dry-run                              Simulate execution without changes.\n  --branch \u003cbranch\u003e                      Branch to run on, defaults to current.\n  --name \u003cname\u003e                          Unscoped project name. Auto-detected from package.json.\n  --scope \u003cscope\u003e                        Org/user scope without \"@\". Auto-detected from package.json.\n  --base \u003cbase\u003e                          Relative path from repository root to project root. Useful for monorepos. (default: \"\")\n  --changelog-path \u003cchangelog-path\u003e      Changelog file path, relative to project root. (default: \"CHANGELOG.md\")\n  --bump-strategy \u003cbump-strategy\u003e        \"auto\" (from commits) or \"manual\" (user-specified). (default: \"\")\n  --release-type \u003crelease-type\u003e          The release type to bump.\n  --pre-release-id \u003cpre-release-id\u003e      Pre-release ID (e.g., \"alpha\", \"beta\"). (default: \"alpha\")\n  --pre-release-base \u003cpre-release-base\u003e  Starting version for pre-releases.\n  --release-notes \u003crelease-notes\u003e        Custom release notes for changelog. (default: \"\")\n  --commit-message \u003ccommit-message\u003e      Commit message template with placeholders. (default: \"chore(release): release {{name}}@{{version}}\")\n  --tag-name \u003ctag-name\u003e                  Tag name template with placeholders. (default: \"{{name}}@{{version}}\")\n  --skip-bump                            Skip version bump step.\n  --skip-changelog                       Skip changelog generation step.\n  --skip-push                            Skip push step.\n  --skip-github-release                  Skip GitHub release step.\n  --skip-git                             Skip all git-related steps.\n  --skip-preflight-check                 Skip preflight checks.\n  --release-title \u003crelease-title\u003e        GitHub release title with placeholders. (default: \"{{name}}@{{version}}\")\n  --release-latest                       Mark as latest release.\n  --release-pre-release                  Mark as pre-release.\n  --release-draft                        Release as draft version.\n  -h, --help                             display help for command\n```\n\n#### Version Bumping Strategies\n\nFirefly offers two primary strategies for version determination.\n\n##### Automatic Strategy (`--bump-strategy auto`)\n\nThe automatic strategy analyzes your commit history using conventional commit standards to determine the appropriate version increment.\n\n**How It Works:**\n\nFirefly's automatic versioning follows a three-stage process:\n\n1. Fetches all commits since the last Git tag (or all commits if no tags exist)\n2. Parses each commit using conventional commit patterns to extract type, scope, and breaking change indicators\n3. Determines the appropriate version level based on the highest-impact change detected\n\n**Version Level Determination:**\n\nThe system prioritizes changes in the following hierarchy:\n\n- **MAJOR (0)**: Breaking changes take absolute precedence\n  - Commits with `BREAKING CHANGE:` footer\n  - Commits with `!` after type/scope (e.g., `feat!:`, `fix(api)!:`)\n  - Scoped breaking changes\n\n- **MINOR (1)**: New features when no breaking changes exist\n  - `feat:` commit types\n\n- **PATCH (2)**: Bug fixes and maintenance when no features or breaking changes exist\n  - `fix:`, `perf:`, `refactor:`, `style:`, `test:`, `build:`, `ci:`, `chore:`, `docs:`, `security:`\n\n**Commit Analysis:**\n\nThe analyzer performs deep inspection of commit metadata:\n\n- Scans commit headers, bodies, and footers for breaking change indicators\n-  Identifies commits indicating graduation from pre-release to stable versions\n- Properly categorizes revert commits based on what they're reverting\n\n**Repository State Handling:**\n\n- When no Git tags exist, Firefly can either analyze all commits or default to patch increment\n- If no commits exist since the last tag, defaults to patch increment for safety\n- Always selects the highest-impact change (breaking \u003e feature \u003e patch)\n\n\u003e [!NOTE]\n\u003e Analyzer customization is planned for future releases, allowing tailored commit parsing rules and more.\n\n##### Manual Strategy (`--bump-strategy manual`)\n\nThe manual strategy presents you with a generated list of potential version increments based on your current version.\n\n\u003c!-- ```bash\n❯ Select version bump\n● prerelease (3.0.0-alpha.21)\n○ graduate (3.0.0)\n○ patch (3.0.1)\n○ minor (3.1.0)\n○ major (4.0.0)\n```\n\nYou can bypass the prompt by specifying the desired release type directly:\n\n```bash\nfirefly release --release-type minor # 1.0.0 → 1.1.0\n``` --\u003e\n\n- **Prompt**: Interactive selection of the desired version bump\n  ```bash\n  ❯ Select version bump\n  ● prerelease (3.0.0-alpha.21)\n  ○ graduate (3.0.0)\n  ○ patch (3.0.1)\n  ○ minor (3.1.0)\n  ○ major (4.0.0)\n  ```\n\n- **Direct Specification**: Use `--release-type` to specify the desired bump directly\n    ```bash\n    firefly release --release-type minor # 1.0.0 → 1.1.0\n    ```\n\n##### Bumping Pre-Release Versions\n\nFirefly supports comprehensive pre-release versioning for testing and staging workflows.\n\nPre-release versions follow the pattern `major.minor.patch-identifier.number`:\n\n**Pre-release Types:**\n- **premajor**: `1.0.0 → 2.0.0-alpha.0`\n- **preminor**: `1.0.0 → 1.1.0-alpha.0`\n- **prepatch**: `1.0.0 → 1.0.1-alpha.0`\n- **prerelease**: `1.0.0-alpha.0 → 1.0.0-alpha.1`\n\n**Customizing Pre-release Identifiers:**\n\nThe default pre-release identifier is `alpha`, but you can customize it using `--pre-release-id`:\n\n```bash\nfirefly release --bump-strategy manual --release-type preminor --pre-release-id beta\n# Result: 1.0.0 → 1.1.0-beta.0\n```\n\n**Pre-release Base Numbering:**\n\nUse `--pre-release-base` to control the starting number for pre-releases (defaults to 0):\n\n```bash\nfirefly release --release-type prepatch --pre-release-id rc --pre-release-base 1\n# Result: 1.0.0 → 1.0.1-rc.1\n```\n\n## Configuration \u0026 Customization\n\n### The Configuration File\n\nFirefly's configuration system centers around the `firefly.config.ts` file, that should be placed at the root of your project. By default, Firefly doesn't require a configuration file, but it can be used to customize behavior and defaults.\n\n#### Basic Configuration Structure\n\n```ts\nexport default {\n    // Basic project information\n    name: \"my-awesome-package\",\n    scope: \"myorg\",\n\n    // Versioning strategy\n    bumpStrategy: \"auto\",\n\n    // Template customization\n    commitMessage: \"chore(release): release {{name}}@{{version}}\",\n    tagName: \"v{{version}}\",\n    releaseTitle: \"{{name}} v{{version}}\",\n};\n```\n\n#### Project Name and Scope\n\nThe `name` and `scope` configuration options provide fine-grained control over how Firefly identifies and names your project:\n\n**Automatic Detection:**\n\n```json\n// package.json\n{\n  \"name\": \"@myorg/awesome-package\"\n}\n```\nFirefly automatically extracts `scope: \"myorg\"` and `name: \"awesome-package\"`.\n\n**Override for Unscoped Releases:**\n\n```ts\nexport default {\n    name: \"awesome-package\",\n    scope: \"\", // Explicitly disable scope\n};\n```\n\n**Custom Naming for Monorepos:**\n\n```ts\n// packages/languages/firefly.config.ts\nexport default {\n    name: \"languages\",\n    scope: \"project-imperia\",\n    base: \"packages/languages\", // Path from repo root\n};\n```\n\n#### Templating for Release Artifacts\n\nFirefly's templating system enables dynamic content generation across commit messages, tag names, and release titles.\n\nTemplates use double-brace syntax and support several powerful variables:\n\n##### Available Template Variables\n\n- `{{name}}`: The complete project name, including scope if present (`@myorg/package` or `package`)\n- `{{unscopedName}}`: The project name without scope (`package`)\n- `{{version}}`: The new version being released (`1.2.0`)\n\n##### Customizing Commit Messages\n\nDefault: `\"chore(release): release {{name}}@{{version}}\"`\n\n```ts\nexport default {\n    commitMessage: \"chore: bump {{name}} version {{version}}\",\n    // Result: \"chore: bump @myorg/package version 1.2.0\"\n};\n```\n\n##### Customizing Tag Names\n\nDefault: `\"{{name}}@{{version}}\"`\n\n```ts\nexport default {\n    tagName: \"v{{version}}\", // Simple semantic versioning tags\n    // Result: \"v1.2.0\"\n\n    // Or for scoped packages:\n    tagName: \"{{unscopedName}}-{{version}}\",\n    // Result: \"package-1.2.0\"\n};\n```\n\n##### Customizing Release Titles\n\nDefault: `\"{{name}}@{{version}}\"`\n\n```ts\nexport default {\n    releaseTitle: \"Release {{unscopedName}} {{version}}\",\n    // Result: \"Release package 1.2.0\"\n};\n```\n\n##### Customizing Release Notes\n\n```ts\nexport default {\n    releaseNotes: \"This release includes important updates to {{unscopedName}}. See changelog for details.\",\n};\n```\n\nOr `--release-notes` flag to provide custom release notes directly via CLI.\n\n\u003e See [git-cliff \u003e Adding Tag Messages](https://git-cliff.org/docs/usage/adding-tag-messages/) on how to include release notes in the changelog.\n\n#### Skipping Release Steps\n\nFirefly provides granular control over which steps to execute, enabling flexible workflows for different scenarios:\n\n**Common Skip Patterns:**\n\n```bash\n# Skip changelog\nfirefly release --skip-changelog\n\n# Skip GitHub release\nfirefly release --skip-github-release\n\n# Dry run to preview changes\nfirefly release --dry-run\n```\n\n### Integrating with git-cliff\n\nFirefly leverages git-cliff's powerful changelog generation capabilities while respecting your existing configuration.\n\n**Configuration Discovery**\n\nFirefly automatically locates `cliff.toml` at the root of your project.\n\n**Basic cliff.toml for conventional commits:**\n\n```toml\n[changelog]\nbody = \"\"\"\n{% if version %}\\\n    ## [{{ version | trim_start_matches(pat=\"v\") }}] - {{ timestamp | date(format=\"%Y-%m-%d\") }}\n{% else %}\\\n    ## [unreleased]\n{% endif %}\\\n{% for group, commits in commits | group_by(attribute=\"group\") %}\n    ### {{ group | striptags | trim | upper_first }}\n    {% for commit in commits %}\n        - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\\\n            {% if commit.breaking %}[**breaking**] {% endif %}\\\n            {{ commit.message | upper_first }}\\\n    {% endfor %}\n{% endfor %}\n\"\"\"\ntrim = true\nrender_always = true\n\n[git]\nconventional_commits = true\nfilter_unconventional = true\nrequire_conventional = false\nsplit_commits = false\nprotect_breaking_commits = false\ncommit_parsers = [\n    { message = \"^feat\", group = \"\u003c!-- 0 --\u003e🚀 Features\" },\n    { message = \"^fix\", group = \"\u003c!-- 1 --\u003e🐛 Bug Fixes\" },\n    { message = \"^doc\", group = \"\u003c!-- 3 --\u003e📚 Documentation\" },\n    { message = \"^perf\", group = \"\u003c!-- 4 --\u003e⚡ Performance\" },\n    { message = \"^refactor\", group = \"\u003c!-- 2 --\u003e🚜 Refactor\" },\n    { message = \"^style\", group = \"\u003c!-- 5 --\u003e🎨 Styling\" },\n    { message = \"^test\", group = \"\u003c!-- 6 --\u003e🧪 Testing\" },\n    { message = \"^chore\\\\(release\\\\): prepare for\", skip = true },\n    { message = \"^chore\\\\(deps.*\\\\)\", skip = true },\n    { message = \"^chore\\\\(pr\\\\)\", skip = true },\n    { message = \"^chore\\\\(pull\\\\)\", skip = true },\n    { message = \"^chore|^ci\", group = \"\u003c!-- 7 --\u003e⚙️ Miscellaneous Tasks\" },\n    { body = \".*security\", group = \"\u003c!-- 8 --\u003e🛡️ Security\" },\n    { message = \"^revert\", group = \"\u003c!-- 9 --\u003e◀️ Revert\" },\n    { message = \".*\", group = \"\u003c!-- 10 --\u003e💼 Other\" },\n]\nfilter_commits = false\nlink_parsers = []\nuse_branch_tags = false\ntopo_order = false\ntopo_order_commits = true\nsort_commits = \"oldest\"\nrecurse_submodules = false\n```\n\n\u003e For more customization options, refer to the [git-cliff \u003e Configuration](https://git-cliff.org/docs/configuration).\n\n## License\n\nThis project is licensed under the [MIT license](LICENSE).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyehezkieldio%2Ffirefly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyehezkieldio%2Ffirefly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyehezkieldio%2Ffirefly/lists"}