From 0379788a19a9106fb4bf165181e7404eacc94aec Mon Sep 17 00:00:00 2001
From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
Date: Sat, 23 Sep 2023 07:56:28 +0200
Subject: [PATCH] docs: update best practices (#22233)

Co-authored-by: Morre <morre@mor.re>
Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
Co-authored-by: Rhys Arkins <rhys@arkins.net>
---
 docs/usage/.pages                    |   1 +
 docs/usage/reading-list.md           |   1 +
 docs/usage/upgrade-best-practices.md | 280 +++++++++++++++++++++++++++
 3 files changed, 282 insertions(+)
 create mode 100644 docs/usage/upgrade-best-practices.md

diff --git a/docs/usage/.pages b/docs/usage/.pages
index 96f2eecaa2..c06086d970 100644
--- a/docs/usage/.pages
+++ b/docs/usage/.pages
@@ -29,6 +29,7 @@ nav:
       - 'Updating and Rebasing Branches': 'updating-rebasing.md'
       - 'Semantic Commit Messages': 'semantic-commits.md'
       - 'Noise Reduction': 'noise-reduction.md'
+      - 'Upgrade best practices': 'upgrade-best-practices.md'
   - Included Presets:
       - 'Default Presets': 'presets-default.md'
       - 'Docker Presets': 'presets-docker.md'
diff --git a/docs/usage/reading-list.md b/docs/usage/reading-list.md
index ca1b0929e3..40834b5917 100644
--- a/docs/usage/reading-list.md
+++ b/docs/usage/reading-list.md
@@ -44,6 +44,7 @@ Start by reading:
 First, complete the "Beginners" reading list.
 Read this list _after_ experiencing Renovate's default behavior, once you really want/need to make changes to Renovate's behavior.
 
+- [Upgrade best practices](./upgrade-best-practices.md)
 - [Key concepts, presets](./key-concepts/presets.md)
 - [Key concepts, Renovate scheduling](./key-concepts/scheduling.md)
 - [Key concepts, automerge](./key-concepts/automerge.md)
diff --git a/docs/usage/upgrade-best-practices.md b/docs/usage/upgrade-best-practices.md
new file mode 100644
index 0000000000..99838d3cbe
--- /dev/null
+++ b/docs/usage/upgrade-best-practices.md
@@ -0,0 +1,280 @@
+# Upgrade best practices
+
+This page explains what we (the Renovate maintainers) recommend you do to update your dependencies.
+
+We'll cover starting a new project, updating a year-old project, and updating a project with five year old dependencies.
+We explain why you should update often, and how to nudge your team to update their dependencies.
+
+## General recommendations
+
+In general, you should:
+
+- Run Renovate on _every_ repository
+- Use the `config:best-practices` preset instead of `config:recommended`
+- Use the Dependency Dashboard issue (it's on by default)
+- Update your dependencies often
+- Read the changelogs for the updates
+- Update to new `major` versions in good time
+- Talk with your team about the update strategy
+
+If Renovate is too noisy for you, read the [noise reduction docs](./noise-reduction.md).
+
+## Use the `config:best-practices` preset
+
+The `config:recommended` preset is the recommended configuration for most Renovate users.
+Renovate also has a `config:best-practices` preset that includes our upgrade best practices.
+
+You should extend from the `config:best-practices` preset:
+
+```json
+{
+  "extends": ["config:best-practices"]
+}
+```
+
+If you're using `config:recommended` now, replace it with `config:best-practices`:
+
+```diff
+- "extends": ["config:recommended"]
++ "extends": ["config:best-practices"]
+```
+
+### What's in the `config:best-practices preset?
+
+The [`config:best-practices` preset](https://docs.renovatebot.com/presets-config/#configbest-practices) has this configuration:
+
+```json
+{
+  "configMigration": true,
+  "extends": [
+    "config:recommended",
+    "docker:pinDigests",
+    "helpers:pinGitHubActionDigests",
+    ":pinDevDependencies"
+  ]
+}
+```
+
+The next sections explain each part of the preset.
+
+#### Config migration
+
+Renovate creates a config migration PR to replace old config option names with their new replacements.
+This way your configuration file and the Renovate docs always use the same terms.
+
+You'll get config migration PRs no matter _how_ you run Renovate: self-hosting or the Mend Renovate app.
+
+#### Extends `config:recommended`
+
+The `config:recommended` preset is a good base to start from.
+That's why we extend from it.
+
+#### Extends `docker:pinDigests`
+
+The [Renovate docs, Docker Digest pinning](./docker.md#digest-pinning) section explains _why_ you should pin your Docker containers to an exact digest.
+
+#### Extends `helpers:pinGitHubActionDigests`
+
+The [GitHub Docs, using third-party actions](https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions) recommend that you pin third-party GitHub Actions to a full-length commit SHA.
+
+We recommend pinning _all_ Actions.
+That's why the `helpers:pinGitHubActionDigests` preset pins all GitHub Actions.
+
+For an in-depth explanation why you should pin your Github Actions, read the [Palo Alto Networks blogpost about the GitHub Actions worm](https://www.paloaltonetworks.com/blog/prisma-cloud/github-actions-worm-dependencies/).
+
+#### Extends `:pinDevDependencies`
+
+Pinning your development dependencies means you, and your team, are using the same versions of development tools.
+This makes the developer-tool side of your builds reproducible.
+Debugging faulty versions of your tools is easier, because you can use Git to check out different versions of the tools.
+
+### Why updating often is easier, faster and safer
+
+You may think that updating takes too much time.
+But updating regulary actually _saves_ you time, because:
+
+- Regular updates tend to be small
+- Applying `major` updates is easier
+- You'll be ready for CVE patches
+- You'll look for ways to automate the updates
+
+#### Regular updates tend to be small
+
+Firstly, when you update regularly updates tend to be small.
+The update's changelogs are small, quick to read, and easy to understand.
+You probably only need to make changes in a few places (if at all) to merge the PR and get going again.
+Because you're reading the changelogs regularly, you'll get a feel for the direction of the upstream project.
+
+#### Applying `major` updates is easier
+
+Secondly, when you're current with upstream, `major` updates are easier.
+This is because you already:
+
+- follow the latest best practices of upstream
+- use the latest names for features/variables
+- read the previous changelogs
+
+#### You'll be ready for CVE patches
+
+Thirdly, you'll be ready when a upstream package releases a patch for a critical CVE.
+If you're current, you can review and merge Renovate's PR quickly.
+
+When you're behind on updates, you'll have a bad time, because you must read _more_ changelogs and make _more_ changes before you can merge the critical patch.
+
+#### You'll look for ways to automate the updates
+
+Finally, when you're updating often, you'll start looking for ways to automate the updates.
+You may start to [`automerge`](./configuration-options.md#automerge) development dependencies like Prettier, or ESLint when the linter passes.
+Or you may decide to automerge any `patch` type upgrades, by using the [`default:automergePatch`](https://docs.renovatebot.com/presets-default/#automergepatch) preset.
+
+You may also start using [GitHub's pull request merge queues](./key-concepts/automerge.md#github-merge-queue) to speed up the merge process.
+Renovate does not support GitLab's Merge Trains, see [issue #5573](https://github.com/renovatebot/renovate/issues/5573).
+
+## Starting from a new project
+
+Let's assume you're starting a new project.
+You created a new Git repository, installed the latest frameworks, libraries and development tools.
+After pushing the initial commit, you should enable and onboard Renovate.
+
+Now you'll have to stay on the "update often" train.
+
+## Project with one year old dependencies
+
+If you have a project that's a year behind on dependencies, you'll need to do some work.
+Let's assume that most dependencies need a `patch` or `minor` update, and at _least_ one dependency needs a `major` update.
+
+Start small, and get the `patch` and `minor` updates first.
+Read the changelogs for your updates.
+You may have to make small changes to get things working again.
+
+When you have the latest `patch` and `minor` versions, you are ready for `major` updates.
+Start with `major` version updates for tools like Prettier or ESLint.
+
+Then work on `major` updates for your framework or library.
+Take your time, read the changelogs, and make the necessary changes.
+Let multiple team members review your work before merging, it's easy to miss something.
+
+Finally, update your development tools.
+
+Now you're up to date, you should think how to make updating a regular habit.
+
+## Project with five year old dependencies
+
+Let's assume your Dependency Dashboard lists more than 50 updates, and you have a few `major` version updates pending.
+If your project is this badly behind on updates, you have two problems:
+
+- Updating your dependencies
+- Improving your update process
+
+### Focus on critical updates first
+
+Fix the easier problem first: getting back up to date.
+Update any dependencies that have critical updates for CVEs or other security related improvements.
+
+If you're on the GitHub platform: follow the steps listed in the [`vulnerabilityAlerts`](./configuration-options.md#vulnerabilityalerts) docs to make sure Renovate is reading GitHub's Vulnerability Alerts.
+
+You may want to enable the experimental `osvVulnerabilityAlerts` config option, to get OSV-based vulnerability alerts for _direct_ dependencies.
+Read the [`osvVulnerabilityAlerts` config option docs](./configuration-options.md#osvvulnerabilityalerts) to learn more.
+
+### Fix blocking updates
+
+Next, update any dependency that's blocking another update.
+You may need to update dependency `A` before you can update dependency `B` or `C`.
+In that case, update dependency `A` first.
+
+### Update to latest `minor` or `patch` of current version
+
+Then update all dependencies to their latest `minor` or `patch` version, to prepare for the `major` updates.
+
+### Take `major` updates in sequence
+
+Take `major` updates in sequence.
+This way you'll read the changelogs for each `major` version, and learn _why_ upstream made certain breaking changes.
+
+Say you're on version `1` of a dependency, and the latest `major` version is at `4`.
+You should update to `2`, then `3` and finally `4`.
+Avoid updating from `1` directly to `4`.
+
+Use the [`:separateMultipleMajorReleases`](https://docs.renovatebot.com/presets-default/#separatemultiplemajorreleases) preset to get separate `major` updates.
+
+### Update development tools
+
+Finally update development tools like Prettier, ESLint, TSLint, Cypress, and so on.
+
+### Improve the human side
+
+You're done with the _technical_ side.
+Now comes the harder part, fixing the _human_ side.
+There are probably a number of reasons why the project got this badly out of date.
+
+When working on the human side, focus on the process, rules, and habits.
+Avoid blaming developers for not updating often.
+
+## Why developers avoid updating
+
+Let's assume most developers _want_ a project that's up to date.
+So why are your developers avoiding updates?
+Some common reasons:
+
+- Developers get blamed when things break in production
+- There are no tests, so merging updates is scary
+- The test suite is slow
+- Releasing a new version of the project must be done by hand
+- Updating must be done by hand
+- The company doesn't allow developer time for updates
+- The company has complex rules about updates
+
+If updating is painful, or takes a lot of time, developers tend to avoid it.
+Make it easy and fast to update dependencies.
+
+### Talk with your team about the update process
+
+Listen to your team, write down their problems.
+Then fix each problem as best as you can.
+
+### Make updating easy and fast
+
+Respect your developer's time and brains:
+
+- Run Renovate on _all_ projects
+- Use Renovate to propose updates
+- Building the project _must_ be as fast as possible
+- Have automated tests for the critical path of your project
+- Run the automated tests on _every_ pull request
+- If you're on GitHub: use [GitHub's Merge Queue](./key-concepts/automerge.md#github-merge-queue) to speed up merges
+- Follow SemVer versioning
+- Use the [`semantic-release` bot](https://github.com/semantic-release/semantic-release) to automate the release process
+- Refactor existing code to make future changes easier
+
+#### Ground rules
+
+As a starting point:
+
+- Avoid long lived branches that diverge from `main` over time
+- Dig beyond "developer error" when things go wrong, again: focus on the process
+- Ensure company policy allows frequent updates
+
+## How we use Renovate
+
+- We run Renovate on all repositories
+- Most of our repositories have automated tests for the critical path of the application
+- We automerge some dependencies, but request `major` updates from the Dependency Dashboard
+- When a developer merges a breaking change, we revert to a known-good version, and try again later
+- We automated the release with the [`semantic-release`](https://github.com/semantic-release/semantic-release) bot
+- We spend time to make our build and automated tests as fast as possible
+
+## How others use Renovate
+
+Read the [Swissquote user story](./user-stories/swissquote.md) to see how they use Renovate.
+
+## Recommended reading
+
+There's a lot of good information out there, so we can only highlight a few resources.
+
+Martin Fowler has two great resources:
+
+- The free page [Patterns for Managing Source Code Branches](https://martinfowler.com/articles/branching-patterns.html) to help you decide what Git branch pattern to use
+- The book [Refactoring, Improving the Design of Existing Code](https://martinfowler.com/books/refactoring.html) to help your developers gradually refactor to clean, modular and easy to read code
+
+The `git bisect` command can help you find out which commit introduced a bug, or other behavior change.
+Read the [ProGit 2 book, section on binary search](https://git-scm.com/book/en/v2/Git-Tools-Debugging-with-Git#_binary_search) to learn more.
-- 
GitLab