@@ -75,7 +75,7 @@ case we are releasing a MAJOR version. Conversely, if `P` is not equal
75
75
to zero, we are releasing a PATCH version.
76
76
77
77
1 . Upgrade the Go version used in the ` git-lfs/build-dockers ` repository
78
- to the latest available patch release with the same major and minor
78
+ to the latest available PATCH release with the same major and minor
79
79
version numbers as the Go version used in this repository's GitHub
80
80
Actions workflows.
81
81
@@ -152,7 +152,7 @@ to zero, we are releasing a PATCH version.
152
152
does not need to be signed (but must be annotated). Check that the
153
153
local version of Go is equivalent to the most recent one used by the
154
154
GitHub Actions workflows for the release branch, which may be different
155
- from that used on the `main` branch. For a patch release in particular
155
+ from that used on the `main` branch. For a PATCH release in particular
156
156
you may need to downgrade your local Go version. The build artifacts
157
157
will be placed in the `bin/releases` directory and may be uploaded
158
158
into the PR from there:
@@ -225,7 +225,8 @@ to zero, we are releasing a PATCH version.
225
225
Actions
226
226
[workflow](https://github.com/git-lfs/git-lfs/actions/workflows/release.yml),
227
227
and then unpack the file at the top level of the repository:
228
- ```
228
+
229
+ ```ShellSession
229
230
$ rm -rf bin/releases
230
231
$ unzip /path/to/release-assets.zip
231
232
```
@@ -234,7 +235,7 @@ to zero, we are releasing a PATCH version.
234
235
The `script/upload` utility will create a new draft release announcement
235
236
and then upload the release assets and attach them to the announcement:
236
237
237
- ```
238
+ ```ShellSession
238
239
$ script/upload --skip-verify vM.N.P
239
240
```
240
241
@@ -285,7 +286,7 @@ to zero, we are releasing a PATCH version.
285
286
should correspond with the packaged artifact containing the new
286
287
release's source files which is available at the given URL:
287
288
288
- ```
289
+ ```ShellSession
289
290
$ brew tap homebrew/core
290
291
$ brew bump-formula-pr \
291
292
--url https://github.com/git-lfs/git-lfs/releases/download/vM.N.P/git-lfs-vM.N.P.tar.gz \
@@ -300,7 +301,7 @@ When building a PATCH release, we cherry-pick merges from `main` to the
300
301
and then use that branch as the base for the PATCH release.
301
302
302
303
1. Upgrade or downgrade the Go version used in the `git-lfs/build-dockers`
303
- repository to the latest available patch release with the same major
304
+ repository to the latest available PATCH release with the same major
304
305
and minor version numbers as the Go version used to build the Git LFS
305
306
`vM.N.(P-1)` release.
306
307
@@ -313,7 +314,7 @@ and then use that branch as the base for the PATCH release.
313
314
```
314
315
315
316
If the release branch already exists because this is not the first
316
- patch release for the given MINOR (or MAJOR) release, simply checkout
317
+ PATCH release for the given MINOR (or MAJOR) release, simply checkout
317
318
the `release-M.N` branch, and ensure that you have the latest changes
318
319
from the remote.
319
320
@@ -336,3 +337,281 @@ and then use that branch as the base for the PATCH release.
336
337
337
338
5. Then follow the [guidelines](#building-a-release) above, using the
338
339
`release-M.N` branch as the base for the new PATCH release.
340
+
341
+ ### Building security PATCH versions
342
+
343
+ In our public security [policy](../../SECURITY.md) we request that
344
+ potential vulnerabilities in the Git LFS client be reported to us
345
+ via email. Users sometimes also choose to open draft GitHub security
346
+ advisories, although we do not encourage that option.
347
+
348
+ If we determine that such a report is valid, we develop a PATCH release
349
+ version of the client with a remediation for the security issue,
350
+ following the steps below.
351
+
352
+ 1. Open a new draft security advisory, fill out the relevant
353
+ details in the
354
+ [template](https://github.com/git-lfs/git-lfs/security/advisories/new),
355
+ and request a CVE identifier.
356
+
357
+ 2. Create a temporary private fork of this repository from the draft
358
+ security advisory page, and use the fork to develop a resolution
359
+ of the vulnerability.
360
+
361
+ 3. Create two PRs in the private fork, one to remediate the vulnerability
362
+ in the `main` development branch of the public `git-lfs/git-lfs`
363
+ repository, and one to do so in the appropriate `release-M.N` branch.
364
+
365
+ The PR which targets the release branch should have a final, extra
366
+ commit which adds an entry for the new PATCH release version in the
367
+ `CHANGELOG.md` file, describing the release and the security fix it
368
+ contains. This commit should also include the changes generated
369
+ by the `script/update-version vM.N.P` command, as per the second step
370
+ in our standard release process.
371
+
372
+ If the `release-M.N` branch does not exist in the public repository,
373
+ create it as per our regular PATCH release process, and then create
374
+ the second PR in the private fork against the new branch. Be prepared
375
+ to proceed relatively quickly, since the appearance of the new branch
376
+ serves as a public notice that we may be publishing a PATCH release
377
+ shortly.
378
+
379
+ 4. From the draft security advisory page, use the "Merge pull requests"
380
+ option to merge both PRs simultaneously.
381
+
382
+ Note that both the release branch and the `main` branch in the private
383
+ fork must be up-to-date with the corresponding branches in the public
384
+ repository in order for the GitHub UI to determine whether the PRs have
385
+ no merge conflicts.
386
+
387
+ 5. Publish the security advisory.
388
+
389
+ 6. Follow our standard release process, starting with the step in which
390
+ we create a GPG-signed tag named `vM.N.P` on the merge commit to the
391
+ `release-M.N` branch.
392
+
393
+ 7. After publication of the new release, update the `git-lfs.com` home
394
+ page with a banner message regarding the security PATCH release.
395
+ Place the banner at the top of the `_includes/home/secondary.html`
396
+ file in the `git-lfs/git-lfs.github.com` repository. Use the GHSA
397
+ identifier from the security advisory, and remove any previous
398
+ security message banners.
399
+
400
+ ```html
401
+ <div class="column">
402
+ <a class="dot-com-announcement" data-ga-params="banner"
403
+ href="https://github.com/git-lfs/git-lfs/security/advisories/GHSA-abcd-1234-wxyz">
404
+ Git LFS security update: <span>All users should update to M.N.P or newer</span>.</a>
405
+ </a>
406
+ </div>
407
+ ```
408
+
409
+ 8. Create a new discussion in the "Announcements" section of the GitHub
410
+ discussion [forum](https://github.com/git-lfs/git-lfs/discussions)
411
+ describing the security PATCH release, and pin the discussion for
412
+ all categories in the forum.
413
+
414
+ ### Building security PATCH versions under embargo
415
+
416
+ When coordinating the release of a security patch with one or more
417
+ other projects, we must not follow the processes described above as
418
+ they depend on the GitHub Actions release workflow in our public
419
+ `git-lfs/git-lfs` repository. Instead, we use a private repository
420
+ with a modified release workflow to build the binaries and packages
421
+ for our new version so that we can share them with the other projects
422
+ in advance of the coordinated release date.
423
+
424
+ 1. Open a draft security advisory, apply for a CVE identifier, and
425
+ create a temporary private fork from the advisory page. Develop a
426
+ resolution of the vulnerability in the private fork. These initial
427
+ steps are the same as those of our non-embargoed security PATCH
428
+ release process.
429
+
430
+ 2. Create one PR in the private fork to remediate the vulnerability
431
+ in the `main` development branch of the public repository.
432
+
433
+ 3. Create a branch in the private fork from the appropriate
434
+ `release-M.N` branch, or if that does not yet exist, from the
435
+ appropriate `vM.N.0` tag, and add the necessary changes to remediate
436
+ the vulnerability.
437
+
438
+ This branch should have one extra, final commit which adds an entry
439
+ for the new PATCH release version in the `CHANGELOG.md` file,
440
+ describing the release and the security fix it contains. This
441
+ commit should also include the changes generated by the
442
+ `script/update-version vM.N.P` command, as per the second step
443
+ in our standard release process.
444
+
445
+ 4. Pull this branch from the private fork of the public repository
446
+ and push it into a separate private repository which has a fresh copy
447
+ of the public `git-lfs/git-lfs` repository, and for which our full
448
+ CI and release GitHub Actions workflows are configured and enabled.
449
+
450
+ Note that the private fork created from the draft security advisory
451
+ will not execute GitHub Actions jobs, and so we require the use of
452
+ a separate private repository to run a modified release workflow.
453
+
454
+ 5. If the `release-M.N` branch does not exist, create it in the
455
+ separate private repository from the `vM.N.0` tag, as described
456
+ in the second step of our regular PATCH release process.
457
+
458
+ 6. Merge the branch containing the security fix and the commit with the
459
+ new `CHANGELOG.md` entry (and `script/update-version vM.N.P` changes)
460
+ into the `release-M.N` branch, and sign the merge commit with your
461
+ GPG key:
462
+
463
+ ```ShellSession
464
+ $ git checkout release-M.N
465
+ $ git merge --no-ff -S \
466
+ -m "Merge pull request from GHSA-abcd-1234-wxyz" \
467
+ -m "release: M.N.P" \
468
+ branch-with-fix-and-changelog
469
+ ```
470
+
471
+ Use the GHSA identifier from the draft security advisory in the
472
+ merge commit's description.
473
+
474
+ 7. Create a GPG-signed tag named `vM.N.P` on the merge commit, using
475
+ the same command from the equivalent step of our standard release
476
+ process:
477
+
478
+ ```ShellSession
479
+ $ git tag -s vM.N.P -m vM.N.P
480
+ ```
481
+
482
+ 8. Check out the `main` branch of the private repository and make
483
+ the following revisions to the `.github/workflows/release.yml` file,
484
+ and then push these changes back to the private repository's `main`
485
+ branch.
486
+
487
+ First, change the `on` value to `workflow_dispatch`:
488
+
489
+ ```diff
490
+ -on:
491
+ - push:
492
+ - tags: '*'
493
+ +on: workflow_dispatch
494
+ ```
495
+
496
+ Set the version of Go in each `matrix` context to the same version
497
+ used in the Dockerfiles from our `git-lfs/build-dockers` repository.
498
+
499
+ Replace the `${{ github.ref }}` context wherever it appears with the
500
+ `vM.N.P` tag:
501
+
502
+ ```diff
503
+ - ref: ${{ github.ref }}
504
+ + ref: vM.N.P
505
+ ```
506
+
507
+ Revise the `build-docker` and `build-docker-arm` jobs so they do not
508
+ upload the Linux packages generated by the `docker/run_dockers.bsh`
509
+ script to Packagecloud by running the `script/packagecloud.rb` utility.
510
+ Change the jobs to instead upload the Linux packages as job artifacts;
511
+ for instance, for the `build-docker` job:
512
+
513
+ ```yaml
514
+ - uses: actions/upload-artifact@v4
515
+ with:
516
+ name: docker-assets
517
+ path: |
518
+ repos/**/*.deb
519
+ repos/**/*.rpm
520
+ ```
521
+
522
+ Make sure to use distinct artifact `name`s for each of these jobs,
523
+ i.e., `docker-assets` and `docker-arm-assets`.
524
+
525
+ 9. Push the `vM.N.P` tag to the private repository, and then cancel
526
+ the GitHub Actions job which runs from the release workflow.
527
+
528
+ (This workflow will run because the tag includes our normal
529
+ GitHub Actions workflow definitions without the changes made in
530
+ the previous step, since those exist only on the `main` branch,
531
+ and we do not want to include these temporary workflow changes in
532
+ the security release itself.)
533
+
534
+ Confirm that the CI workflow job succeeds.
535
+
536
+ 10. From the private repository's GitHub Actions page, manually dispatch
537
+ the release workflow.
538
+
539
+ 11. When the manually-dispatched job is complete, download the
540
+ `release-assets`, `docker-assets`, and `docker-arm-assets` archive
541
+ files from the "Artifacts" section of the job's "Summary" page.
542
+
543
+ Share the relevant binaries from the archive files with the other
544
+ collaborating projects during the embargo period.
545
+
546
+ 12. Before the embargo is due to the lifted, unpack the `release-assets`
547
+ archive file at the top level of this repository and use the
548
+ `script/upload` utility to create a draft release announcement and
549
+ attach the release assets to it, just as for a standard release:
550
+
551
+ ```ShellSession
552
+ $ rm -rf bin/releases
553
+ $ unzip /path/to/release-assets.zip
554
+
555
+ $ script/upload --skip-verify vM.N.P
556
+ ```
557
+
558
+ 13. When the embargo is lifted, use the "Merge pull requests" option
559
+ on the draft security advisory page to merge the PR with the security
560
+ fix into the `main` branch of the public repository.
561
+
562
+ Note that the `main` branch in the private fork must be up-to-date
563
+ with the corresponding branch in the public repository in order for
564
+ the GitHub UI to determine whether the PR has no merge conflicts.
565
+
566
+ 14. Publish the security advisory.
567
+
568
+ 15. Pull the `release-M.N` branch and `vM.N.P` tag from the private
569
+ repository where the release workflow was run manually, and push
570
+ them into the public `git-lfs/git-lfs` repository.
571
+
572
+ Immediately cancel the GitHub Actions job which runs from the
573
+ release workflow in the public repository.
574
+
575
+ Note that cancelling the release workflow job is important, since
576
+ it will otherwise build new versions of the RPM and Debian Linux
577
+ packages and publish them to Packagecloud.
578
+
579
+ 16. Upload to Packagecloud the RPM and Debian Linux packages in the
580
+ `docker-assets` and `docker-arm-assets` archive files created earlier
581
+ by the manual release workflow job.
582
+
583
+ Note that the `script/packagecloud.rb` utility requires the
584
+ `PACKAGECLOUD_TOKEN` environment variable to contain the current
585
+ Packagecloud account credential token.
586
+
587
+ ```ShellSession
588
+ $ mkdir repos
589
+ $ unzip -d repos /path/to/docker-assets.zip
590
+ $ unzip -d repos /path/to/docker-arm-assets.zip
591
+
592
+ $ gem install packagecloud-ruby
593
+ $ PACKAGECLOUD_TOKEN="<token>" script/packagecloud.rb
594
+ ```
595
+
596
+ 17. Finalize the release process using the `script/upload` utility with
597
+ the `--finalize` option. The script will add GPG signatures to the
598
+ `hashes` and `sha256sums` files and then upload the signed files:
599
+
600
+ ```ShellSession
601
+ $ script/upload --finalize vM.N.P
602
+ ```
603
+
604
+ 18. Publish the release announcement.
605
+
606
+ 19. Update the `_config.yml` file in the `git-lfs/git-lfs.github.com`
607
+ repository with the new `M.N.P` release version and push the change,
608
+ as described in the final steps of our standard release process.
609
+
610
+ In addition, update the `_includes/home/secondary.html` file with
611
+ a banner message regarding the security PATCH release, and push
612
+ the change.
613
+
614
+ 20. Create a new discussion in the "Announcements" section of the GitHub
615
+ discussion [forum](https://github.com/git-lfs/git-lfs/discussions)
616
+ describing the security PATCH release, and pin the discussion for
617
+ all categories in the forum.
0 commit comments