The core team of Git LFS maintainers publishes releases on a cadence of their determining.
We follow Semantic Versioning standards as follows:
-
MAJORreleases are done on a scale of 2-4 years. These encompass breaking, incompatible API changes, or command-line interface changes that would cause existing programs or use-cases scripted against Git LFS to break. -
MINORreleases are done on a scale of 2-6 months. These encompass new features, bug fixes, and other "medium"-sized changes into a semi-regular release schedule. -
PATCHreleases are done on the scale of weeks to months. These encompass critical bug fixes, but lack new features. They are amended to aMINORrelease "series", or, if serious enough (e.g., security vulnerabilities, etc.) are backported to previous versions.
We package several artifacts for each tagged release. They are:
-
git-lfs-@{os}-v@{release}-@{arch}.tar.gzfor the following values:operating system architecture git-lfs-darwin-amd64-v@{version}.tar.gz darwin amd64 git-lfs-darwin-arm64-v@{version}.tar.gz darwin arm64 git-lfs-freebsd-386-v@{version}.tar.gz freebsd 386 git-lfs-freebsd-amd64-v@{version}.tar.gz freebsd amd64 git-lfs-linux-386-v@{version}.tar.gz linux (generic) 386 git-lfs-linux-amd64-v@{version}.tar.gz linux (generic) amd64 git-lfs-linux-arm-v@{version}.tar.gz linux (generic) arm git-lfs-linux-arm64-v@{version}.tar.gz linux (generic) arm64 git-lfs-linux-ppc64le-v@{version}.tar.gz linux (generic) ppc64le git-lfs-linux-s390x-v@{version}.tar.gz linux (generic) s390x -
git-lfs-windows-v@{release}-@{arch}.zipfor the following values:operating system architecture git-lfs-windows-386-v@{version}.zip windows 386 git-lfs-windows-amd64-v@{version}.zip windows amd64 git-lfs-windows-arm64-v@{version}.zip windows arm64 -
git-lfs-windows-v@{release}.exe, a signed Windows installer that contains copies of both-x86and-x64copies of Git LFS. -
*.deb, and*.rpmpackages for all of the distributions named inscript/packagegcloud.rb.
We do all major development on the main branch, and assume it to be passing
tests at all times. New features are added via the feature-branch workflow, or
(optionally) from a contributor's fork.
This is done so that main can progress and grow new features, while
historical releases such as vM.N.0 can receive bug fixes as they are applied
to main, eventually culminating in a vM.N.1 (and so on) release.
Let release vM.N.P denote the version that we are releasing.
When P is equal to zero, we say that we are releasing a MINOR version of
Git LFS in the vM.N-series, unless N is also equal to zero, in which
case we are releasing a MAJOR version. Conversely, if P is not equal
to zero, we are releasing a PATCH version.
-
First, we write the release notes and do the housekeeping required to indicate a new version. For a MAJOR or MINOR version, we start with a
mainbranch which is up to date with the latest changes from the remote and then checkout a newrelease-nextbranch from that base.If we are releasing a PATCH version, we create a
release-M.Nbranch with cherry-picked merges from themainbranch, as described in the instructions below, and then checkout therelease-nextbranch from that base.We next perform the following steps to prepare the
release-nextbranch:-
Run
script/changelogand categorize each merge commit as a feature, bug fix, miscellaneous change, or a change to be skipped and ignored. Ensure that your~/.netrccredentials are up-to-date in order to make requests to the GitHub API, or use aGITHUB_TOKENenvironment variable.The
changelogscript will write a portion of the new CHANGELOG to stdout, which you should copy and paste intoCHANGELOG.md, along with an H2-level heading containing the new version and the expected release date. This heading should be consistent with the exising style in the document.For a MAJOR release, use
script/changelog v(M-1).L.0...HEAD, where(M-1)is the previous MAJOR release number andLis the final MINOR release number in that series. For a MINOR release, usescript/changelog vM.(N-1).0...HEAD, where(N-1)is the previous MINOR release number, and for a PATCH release, usescript/changelog vM.N.(P-1)...HEAD, where(P-1)is the previous PATCH release number.-
Optionally write 1-2 paragraphs summarizing the release and calling out community contributions.
-
If we are releasing a MAJOR or MINOR version and not a PATCH, and if the most recent non-PATCH release was followed by a series of one or more PATCH releases, include any changes listed in the CHANGELOG of that series' release branch in the new release's CHANGELOG. (For a new MAJOR version, the prior release branch would be named
release-(M-1).L, following the terminology defined above, while for a new MINOR version the prior release branch would be namedrelease-M.(N-1).)
-
-
Run
script/update-version vM.N.Pto update the version number in all of the relevant files. -
Adjust the date in the
debian/changelogentry to reflect the expected release date rather than the current date.
-
-
Then, push the
release-nextbranch and create a pull request with your changes from the branch. If you're building a MAJOR or MINOR release, set the base to themainbranch. Otherwise, set the base to therelease-M.Nbranch.-
Add the
releaselabel to the PR. -
In the PR description, consider uploading builds for implementers to use in testing. These can be generated from a local tag, which does not need to be signed (but must be annotated). The build artifacts will be placed in the
bin/releasesdirectory and may be uploaded from there:$ git tag -m vM.N.P-pre vM.N.P-pre $ make release $ ls bin/releases
-
Notify the
@git-lfs/releasesand@git-lfs/implementersteams, collections of humans who are interested in Git LFS releases. -
Ensure that the normal Continuous Integration workflow for PRs that runs automatically in GitHub Actions succeeds fully.
-
As the GitHub Actions release workflow will not run for PRs, consider creating an annotated tag with the
-presuffix and pushing the tag, which will trigger a run of the release workflow that does not upload artifacts to Packagecloud. Alternatively, in a private clone of the repository, create such a tag from therelease-nextbranch plus one commit to change to the repository name inscript/upload, and push the tag so Actions will run the release workflow. Ensure that the workflow succeeds (excepting the Packagecloud upload step, which will be skipped).
-
-
Once approved and verified, merge the pull request you created in the previous step. Locally, create a GPG-signed tag on the merge commit called
vM.N.P:$ git show -q --pretty=%s%n%b HEAD Merge pull request #xxxx from git-lfs/release-next release: vM.N.P $ git tag -s vM.N.P -m vM.N.P $ git describe HEAD vM.N.P $ git show -q --pretty=%s%d%n%b vM.N.P tag vM.N.P Tagger: ... vM.N.P -----BEGIN PGP SIGNATURE----- ... -----END PGP SIGNATURE----- Merge pull request #xxxx from git-lfs/release-next (tag: vM.N.P) release: vM.N.P
-
Push the tag, via:
$ git push origin vM.N.PThis will kick off the process of building the release artifacts. This process will take somewhere between 45 minutes and an hour. When it's done, you'll end up with a draft release in the repository for the version in question.
-
From the command line, finalize the release process by signing the release:
$ script/upload --finalize vM.N.PNote that this script requires GnuPG as well as Ruby (with the OpenSSL gem) and several other tools. You will need to provide your GitHub credentials in your
~/.netrcfile or via aGITHUB_TOKENenvironment variable.If you want to inspect the data before approving it, pass the
--inspectoption, which will drop you to a shell and let you look at things. If the shell exits successfully, the build will be signed; otherwise, the process will be aborted. -
Publish the release on GitHub, assuming it looks correct.
-
Move any remaining items out of the milestone for the current release to a future release and close the milestone.
-
Update the
_config.ymlfile ingit-lfs/git-lfs.github.com, similar to the following:--- _config.yml +++ _config.yml @@ -1,7 +1,7 @@ # Site settings title: "Git Large File Storage" description: "Git Large File Storage (LFS) replaces large files such as audio samples, videos, datasets, and graphics with text pointers inside Git, while storing the file contents on a remote server like GitHub.com or GitHub Enterprise." -git-lfs-release: M.(N-1).0 +git-lfs-release: M.N.0 url: "https://git-lfs.com"
-
Create a GitHub PR to update the Homebrew formula for Git LFS with the
brew bump-formula-prcommand on a macOS system. The SHA-256 value should correspond with the packaged artifact containing the new release's source files which is available at the given URL:$ brew bump-formula-pr \ --url https://github.com/git-lfs/git-lfs/releases/download/vM.N.P/git-lfs-vM.N.P.tar.gz \ --sha256 <SHA-256> \ git-lfs
When building a PATCH release, we cherry-pick merges from main to the
vM.N release branch, creating the branch first if it does not exist,
and then use that branch as the base for the PATCH release.
-
If the
release-M.Nbranch does not already exist, create it from the corresponding MINOR release tag (or MAJOR release tag, if no MINOR releases have been made since the last MAJOR release):$ git checkout -b release-M.N vM.N.0If the release branch already exists because this is not the first patch release for the given MINOR (or MAJOR) release, simply checkout the
release-M.Nbranch, and ensure that you have the latest changes from the remote. -
Gather a set of potential candidates to backport to the
release-M.Nbranch with:$ git log --merges --first-parent vM.N.(P-1)...main -
For each merge that you want to backport, run:
$ git cherry-pick -m1 <SHA-1>This will cherry-pick the merge onto your release branch, using the
-m1option to specify that the first parent of the merge corresponds to the mainline. -
Then follow the guidelines above, using the
release-M.Nbranch as the base for the new PATCH release.