{"id":16023480,"url":"https://github.com/followtheprocess/tag","last_synced_at":"2025-04-10T03:37:08.030Z","repository":{"id":37010019,"uuid":"505075219","full_name":"FollowTheProcess/tag","owner":"FollowTheProcess","description":"The all in one semver management tool 🛠️","archived":false,"fork":false,"pushed_at":"2025-04-08T08:09:05.000Z","size":498,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-08T09:26:05.593Z","etag":null,"topics":["go","release-automation","semver"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FollowTheProcess.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2022-06-19T10:18:39.000Z","updated_at":"2025-04-08T08:09:08.000Z","dependencies_parsed_at":"2023-02-18T23:15:44.248Z","dependency_job_id":"ffa17336-c6e9-47d3-a501-f629bb619c80","html_url":"https://github.com/FollowTheProcess/tag","commit_stats":{"total_commits":135,"total_committers":2,"mean_commits":67.5,"dds":0.3851851851851852,"last_synced_commit":"1ec60977dcadf77ccbf3035a3d757e79214aa170"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FollowTheProcess%2Ftag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FollowTheProcess%2Ftag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FollowTheProcess%2Ftag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FollowTheProcess%2Ftag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FollowTheProcess","download_url":"https://codeload.github.com/FollowTheProcess/tag/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248153752,"owners_count":21056486,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["go","release-automation","semver"],"created_at":"2024-10-08T19:01:18.323Z","updated_at":"2025-04-10T03:37:07.998Z","avatar_url":"https://github.com/FollowTheProcess.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://github.com/FollowTheProcess/tag/raw/main/img/logo.png\" alt=\"logo\" width=50% height=50%\u003e\n\u003c/p\u003e\n\n# Tag\n\n[![License](https://img.shields.io/github/license/FollowTheProcess/tag)](https://github.com/FollowTheProcess/tag)\n[![Go Report Card](https://goreportcard.com/badge/github.com/FollowTheProcess/tag)](https://goreportcard.com/report/github.com/FollowTheProcess/tag)\n[![GitHub](https://img.shields.io/github/v/release/FollowTheProcess/tag?logo=github\u0026sort=semver)](https://github.com/FollowTheProcess/tag)\n[![CI](https://github.com/FollowTheProcess/tag/workflows/CI/badge.svg)](https://github.com/FollowTheProcess/tag/actions?query=workflow%3ACI)\n\nThe all in one semver management tool\n\n## Project Description\n\nReleasing new versions of software can be hard! Most projects have CI/CD pipelines set up to help with this and these pipelines are typically triggered on push of a new [semver] tag e.g. `v1.2.4`.\n\nI made tag because I can never remember the commands to correctly issue and push a tag:\n\n* \"Was it `git tag v1.2.4`?\"\n* \"Do I need to annotate it: `git tag -a v1.2.4`?\"\n* \"Do I need to add a message: `git tag -a v1.2.4 -m \"Some message\"`?\n* \"Wait how do I push it again: `git push --tags` or `git push origin v1.2.4`?\"\n\nThis invariably ends up with me doing it differently across every project, spending (even more) time on stackoverflow googling random git commands.\n\nAnd not to mention having to replace versions in documentation, project metadata files etc.\n\nNo more 🚀 `tag` has you covered!\n\n`tag` is cross-platform and is tested on mac, windows and linux. It'll run anywhere you can run Go!\n\n**Fun fact:** `tag` actually releases itself!\n\n## Installation\n\nCompiled binaries for all supported platforms can be found in the [GitHub release]. There is also a [homebrew] tap:\n\n```shell\nbrew install FollowTheProcess/tap/tag\n```\n\n## Usage\n\nTag has 2 modes of operating, one in which it doesn't find a config file in the current directory (`.tag.toml`), and one where it does. Let's start with the first mode.\n\n### No Replace Mode\n\nIf there is no config file present in `cwd`, tag will operate in \"no replace\" mode. This is it's most basic mode and when tag\nis in this mode all you can do with it is list, create, and push new [semver] tags.\n\nFor example let's say you're working on a project currently at `v0.23.8` and you've decided you want to signal to the world that your project is stable, it's time for a major version bump! 🚀\n\nYour project also has a CI/CD pipeline where on the push of a new tag it gets compiled and packaged up and a new release gets created.\n\nSo you need to create a new tag (`v1.0.0`) and push it. No problem!\n\n```shell\ntag major --push\n```\n\nThis will create a new `v1.0.0` annotated git tag, and push it to the configured remote. Job done ✅\n\n### Replace Mode\n\nNow this is already nice but wouldn't it be *even nicer* if you didn't have to manually bump version numbers in project metadata files, or maybe the README:\n\n```markdown\n# My Project Readme\n\nThis my project, version = 0.1.0\n```\n\n`tag` can do that too! All you have to do is tell it what to do with which files to work on, enter the `.tag.toml` config file which should be placed in the root of your repo:\n\n```toml\nversion = '0.1.0'\n\n[[file]]\npath = 'README.md'\nsearch = 'My project, version {{.Current}}'\n\n[[file]]\npath = 'somewhereelse.txt'\nsearch = 'Replace me, version {{.Current}}'\n```\n\nTag uses two special variables `{{.Current}}` and `{{.Next}}` to substitute for the correct versions while bumping as well as the path (relative to `.tag.toml`) of the files you want to change.\n\nSo now all you have to do is e.g.\n\n```shell\ntag minor --push\n```\n\nAnd then tag will:\n\n* Perform search and replace on all occurrences of your search string\n* Stage all the changes in git once the replacing is done\n* Commit the changes with a message like `Bump version 0.1.0 -\u003e 0.2.0`\n* Push the changes\n* Push the new tag\n\nAnd then your CI/CD pipeline will take care of the rest! 🎉\n\nAfter bumping, your README will now look like this:\n\n```markdown\n# My Project Readme\n\nThis my project, version = 0.2.0\n```\n\n## Config File\n\nAs mentioned above, `tag` has an optional config file (`.tag.toml`) to be placed at the root of your repo, we've seen specifying files to search and replace\ncontents on, but it can do a bit more than that!\n\nA fully populated config file looks like this:\n\n```toml\nversion = '0.1.0'\n\n[git]\ndefault-branch = 'main'\nmessage-template = 'Bump version {{.Current}} -\u003e {{.Next}}'\ntag-template = 'v{{.Next}}'\n\n[hooks]\npre-replace = \"echo 'I run before doing anything'\"\npre-commit = \"echo 'I run after replacing but before committing changes'\"\npre-tag = \"echo 'I run after committing changes but before tagging'\"\npre-push = \"echo 'I run after tagging, but before pushing'\"\n\n[[file]]\npath = 'pyproject.toml'\nsearch = 'version = \"{{.Current}}\"'\n\n[[file]]\npath = 'README.md'\nsearch = 'My project, version {{.Current}}'\n```\n\n### Git\n\nThe git section allows you to specify how tag interacts with git whilst bumping versions. You can specify:\n\n* The default branch for your repo (defaults to `main`). This will be checked prior to bumping to ensure you don't issue a tag on a different branch\n* The commit message template (defaults to `Bump version {{.Current}} -\u003e {{.Next}}`). This sets the message used for your bump commit after contents have been replaced\n* The tag message template (defaults to `v{{.Next}}`). Similar to the commit message but this one is associated to the tag itself.\n\n### Hooks\n\nTag also lets you hook into various stages of the replacement/bumping process and inject custom logic in the form of hooks. Hooks are small shell commands that\nlet you update things that tag cannot see or run custom commands.\n\nA good use case is for example, issuing a new version of a rust project with a `Cargo.toml`. In the `Cargo.toml` you must specify a version of your crate:\n\n```toml\n# Cargo.toml\nversion = \"0.1.0\"\n```\n\nWhen you compile your crate, it generates a `Cargo.lock` which *also* has the version. So if you use tag to bump the version in the `Cargo.toml` then the `Cargo.lock` can fall out of sync and then your crate will fail to build. Because we should never really interact with `Cargo.lock` manually, we can use hooks to re-build the crate\nafter replacing the version in `Cargo.toml`:\n\n```toml\n# .tag.toml\n[hooks]\npre-commit = \"cargo build\" # Update the lockfile\n```\n\nThe hooks are split into stages:\n\n* **`pre-replace`**: This one runs first, more or less before tag does *anything* at all\n* **`pre-commit`**: Runs after replacing contents, but before those changes are added and committed to the repo\n* **`pre-tag`**: Runs after replacing and the changes have been committed, but before the new tag is created\n* **`pre-push`**: Runs last, after everything above is finished but before the tag is pushed to the remote (if the `--push` flag is used)\n\n[GitHub release]: https://github.com/FollowTheProcess/tag/releases\n[homebrew]: https://brew.sh\n[semver]: https://semver.org\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffollowtheprocess%2Ftag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffollowtheprocess%2Ftag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffollowtheprocess%2Ftag/lists"}