Roles

  • Admin: performs merges of development branches in the pre-release and main branches. In GitHub, they will have administrative permissions to configure the repository.
  • Reviewer: reviews and approves pull requests, and coordinates with developers if rework is needed.
  • Developer: implements bug fixes and new features. It can be any person at SLAC or even outside SLAC on an external collaboration. Developers can create branches starting from pre-release or a feature branch (the remaining of this document will explain this better) either directly from the official repository or as a GitHub fork.

The remainder of this document will explain the mechanics of the workflow. If you don't understand the concepts described by the policies below, please finish reading the document and come back to this item later.

Software created by SLAC and maintained in its own repositories

Do's and Don'ts of the Workflow

We have 2 protected branches: main and pre-release. By protected we mean that no commits are allowed on those branches, only merges.

  • main: can only receive merges from the pre-release branch. No commits are allowed. No feature branch derived from main is allowed, except for a few rare cases upon request.
  • pre-release: can only receive merges from feature branches. No commits are allowed. Almost all feature branches derive from pre-release.

This is the normal flux, with main receiving merges from pre-release (feature branches are not shown, to simplify the diagram):

Creating a feature branch from pre-release is the regular way to proceed:

Forbidden actions:

Don't merge a feature branch with main.

Don't commit directly to main or pre-release.

Don't create a feature branch starting at main. There may be a few rare cases when this is needed but they will be discussed on a case-by-case basis.

How to proceed with the branches

Always start from pre-release or a feature branch. Name the new branch with a Jira ticket number, a CATER number, or a CATER number plus the job number. This has a few advantages:

  1. Someone who wants to know why the branch was created can just go to CATER or Jira, read the description, and follow the discussion.
  2. In the future, we could add text that goes in RELEASE_NOTES to add a link to the ticket automatically.

If you don't have a Jira ticket or CATER number, then you are missing an important step in the process because all changes in code should be requested by someone and registered in one of these tools.

Examples of branches with good names:

  • GMD-28
  • CATER_12345
  • CATER_56789_job_3

See how all of them originate from pre-release:

An example showing a feature branch originating from another feature branch:

Once you have finished your work you will need to rebase your branch because pre-release could have evolved while you were working. After rebasing, solve conflicts, have everything tested, and proceed with a pull request to the pre-release branch. We have a plan in the future for the code to be auto-tested every time a pull request to the pre-release is made. The Reviewers will check the changes and may ask for modifications if needed. There will be cases when more than 1 Reviewer must approve the pull request so it can be merged with pre-release.

From the example above, let's say that the CATER_12345 Developer finished their work. They don't need to rebase because there was no evolution of the pre-release branch. So, they ask for the pull request and have it approved and merged:

Now the GMD-28 Developer wants to do a pull-request. They see that pre-release already advanced from the point where the branch started, so a rebase is required. This is how GMD-28 looks like after rebase.

Finally, after rebasing, pull request, acceptance, and merge of GMD-28, this is the final result.

After merging, by default the feature branch will be deleted. Recreating the branch, in case it is needed, is a very cheap and quick operation.

Admins will decide when it is time to merge pre-release with main. This will depend on administrative factors, including requests from operations. A complete test will be made in the pre-release HEAD. A pull request must be made. When merging with main, in the future the code will be auto-tested. Again, in some cases, more than 1 Reviewer must approve the pull request.

Maintaining old releases

There are cases when an old release needs to keep receiving commits while the official release is ahead. For example, the official release is 3.2.1, but systems are still using 2.0.0 because they didn't have time to upgrade, yet. In this case, another trunk branch is created with the tag name, plus a dash, plus the word "branch".

The example below shows the case with branch 2.0.0-branch created from tag 2.0.0. The development keeps going in parallel in the main branch. The old release branch receives merges from feature branches, like what happens with pre-release.

Tagging

main branch

All merges from pre-release to main will necessarily be tagged. Modules and packages created and maintained by SLAC are tagged with a three-part version numbering: Major.Minor.Patch.

  • Major: increase this number when substantial changes are made or when something will break compatibility. A change in function arguments, including the ones from the IOC shell may produce a product that is incompatible with the previous versions. Changes in EPICS database macros can cause compatibility problems, too.
  • Minor: this is likely the part of the version number that will be incremented the most. New features and bug fixes cause the increment of this number.
  • Patch: this number is to be incremented when there are changes in configure/RELEASE or configure/CONFIG_SITE, for example. Also, changes in documentation or code style cleanup are examples that increment the patch number.

pre-release branch

Merges in the pre-release branch will not have a tag unless it is requested. Sometimes due to an urgent situation, the module/package needs to be released before it gets merged to the main branch. The tag name will start with the previous tag applied to main, plus a dash, plus the word "pre", plus a 2-digit number starting with 01. So, if the previous main tag was 1.2.3, the first tag on the pre-release will be 1.2.3-pre01, the second one will be 1.2.3-pre02, and so on.

The example below shows tags on all pre-release merges just to increase the number of example cases, but this is not required.

Feature branch

Tags in feature branches are expected to be rare. One possible scenario is during the weeks preceding the commissioning of a device. In this case, the Developer may be producing several releases before being satisfied with the result. In case a tag is needed in a feature branch, the Developer can tag it. The tag name will start with the previous tag applied to main (not pre-release), plus an underscore, plus the name of the branch, plus a dash, plus the word "beta", plus a 2-digit number starting with 01. So, if the previous main version was 1.2.3 and the branch is called CATER_12345, the first tag will be 1.2.3_CATER_12345-beta01, the second one will be 1.2.3_CATER_12345-beta02, and so on.

Old releases kept in parallel with main

The tag will follow the example 2.0.0-0.1.0. In this example, the branch is called 2.0.0-branch. See the diagram here.

General rules

Repository location

  1. Modules and packages under the responsibility of the Embedded Group inside the TID-ACS department will be hosted in GitHub Enterprise. A service will clone the repo frequently to SLAC's internal storage server (AFS or S3DF) as a backup.
  2. All work done in repositories available in GitHub must use GitHub as the remote repo, not AFS or S3DF. Pull requests made from the backup repos in SLAC's storage servers (AFS or S3DF) will not be accepted.
    1. An exception to this rule is during a long GitHub outage if it ever happens.

Transition to GitHub Enterprise

  1. Prior to the migration of the repositories to GitHub, all previous contributors of each module or package will have a period of time to complete pending commits. After this period, the repository will be cleaned:
    1. Abandoned branches will be deleted. All contributors to abandoned branches will be contacted and nothing will be deleted without agreement.
    2. Pending merges will be applied in a work among contributors to the branches.
    3. The master branch will be renamed as main.
  2. After the transition, we recommend that contributors delete their local repositories and clone them again from GitHub.

Branches

  1. In GitHub, each module or package will have two protected branches: main and pre-release. Protected branches are blocked from receiving commits and can receive only merges from other branches. Even Admins and Reviewers are not allowed to commit to the protected branches.
  2. Branching out from the main branch is considered a rare event and allowed on a case-by-case basis.
  3. Only Admins can merge branches into pre-release or main.
  4. Feature branches can be created by any person, either directly from the official repository or as a GitHub fork. The point of origin of a feature branch must be the pre-release branch or another feature branch, but never the main branch. We would like Developers to follow a convention for the branch names, using either Jira tickets or CATER numbers (more details about it in this section on the page). Examples:
    1. GMD-28
    2. CATER_12345
    3. CATER_56789_job_3

  5. Old and inactive feature branches will be deleted.
    1. The branch owner will be contacted before the deletion.

Pull requests

  1. Once a Developer finishes their work, they will check if the pre-release branch advanced while working on the feature branch. If this is the case, a rebase is necessary. After rebasing, use the GitHub pull request mechanism to ask for a merge.
    1. The pull request will be made to the pre-release branch, not main.
      1. In the rare cases when the feature branch started from main, the pull request will be made to the main branch.
  2. The Reviewers will evaluate the changes and may ask the developer to modify the request.
  3. The Reviewers will check not only for source code but also for documentation updates, like READMEs, and if test code is present.
  4. The definition of the number of Reviewers to approve the pull request will be made per repository.
  5. Please allow some time for the Reviewers to evaluate the pull request. Don't expect it will be approved on the same day.
  6. Once the pull request is accepted the Admins will merge the feature branch to pre-release.
    1. If the Reviewer who accepts the pull request also works as an Admin, they can approve and merge in one single operation. 
  7. After the pull request is accepted, by default the feature branch will be deleted:
    1. If the Developer wants to work in the branch after the merge they can simply create a new branch with the same name, an action that takes seconds.
  8. Merging pre-release into main is an action for the Admins and must also follow the pull request workflow described before.
    1. Merging pre-release into main is not anticipated to be a frequent operation. It may happen a few times per year.
      1. An exception to this assumption is in moments when new devices are running for the first time in production. Moments like this will probably trigger multiple merges per month in main.

Tags

  1. People who will be allowed to tag in the pre-release or main branches will be defined per repository. When tagging in pre-release or main, these are examples of naming conventions (more details about it in this section on the page):
    1. For main:
      1. 1.2.3
    2. For pre-release:
      1. 1.2.3-pre02
  2. Every merge from pre-release into main will be tagged.
  3. Tags in the pre-release branch will be made upon request. We don't assume that all merges into pre-release will require a tag.
  4. In the rare cases when a developer needs to tag a commit in the feature branch, we would like them to use a convention like in this example (more details about it in this section on the page):
    1. 1.2.3_CATER_12345-beta02

Software from the external community with customizations from SLAC (to do)

  • No labels