Skip to content

Latest commit

 

History

History
135 lines (107 loc) · 5.59 KB

PROCESSES.md

File metadata and controls

135 lines (107 loc) · 5.59 KB

Processes, release procedures etc

This repository includes multiple projects at multiple versions, some of which depend on each other. That makes things tricky, and leads to rather more complicated procedures than a simple "single package" repository. Please read this guide carefully to understand how releases happen, and why they happen that way.

The API catalog

Only the source within the apis directory is published, although not every project within that directory is published. (There are test projects and tools alongside the production code.) Nothing in the tools directory is published as a package.

Most project files under apis are at least partially generated. The master information is in apis.json - the API catalog file. There's an entry for each API, containing:

  • The kind of API (grpc, rest, other)
  • The version number
  • A product title and home page for documentation
  • Dependencies
  • Additional test project dependencies
  • Target framework versions
  • Package description for NuGet
  • Tags for NuGet (in addition to default ones)

The catalog is used to generate project files and also during the release process described below. Running the project generator is very simple: from the root directory, in a bash shell, run

./generateprojects.sh

The CI systems run this before building, to ensure that the project files are in a stable state.

Generating the project files allows for broad changes (such as adding Source Link support) to be made very simply, just by changing the generator. Modifying every project file by hand simply doesn't scale.

However, sometimes manual editing of project files is required. The project generator supports this by assuming it "owns":

  • The first PropertyGroup element (for general properties)
  • The first ItemGroup element (for dependencies)
  • The ItemGroup element for Source Link (with a label of "dotnet pack instructions")
  • The common import to only attempt to build desktop assemblies on Windows

Any other elements are left as they are - so if you wish to add an ItemGroup such as for file grouping, just add it anywhere after the generated one, and it should do the right thing.

Additionally, for each API, the project generator adds all projects under the API directory (and project references) to the solution for that API. It will create project files from scratch as well - so when adding a new package from autogenerated API sources, the simplest approach is to copy the source files, modify the API catalog, and run the project generator. The project files and solution file will be generated and should immediately be usable.

Versioning

All releasable packages follow Semantic Versioning. Non-releasable code (tests, tools, analyzers) are not versioned. The precise meaning of a breaking change (dictating version number increments) is out of the scope of this document. (Jon is writing a blog post about this topic and will link to it when it is published.)

The version number in the API catalog (and therefore in project files) is one of:

  • The mostly recently released package version
  • The version that's about to be released (see below)
  • A prerelease with a suffix of 00 to indicate that the next release should be the first prerelease for that major/minor version.

The last of these cases can happen if either an existing version has gone to GA and new features have been merged since (to ensure that we don't add features within a minor GA version) or for brand-new APIs that haven't been released at all. The tooling for tagging is aware of this convention, and doesn't create tags for alpha00 or beta00 suffixes.

Typically version numbers should be changed in a commit which does nothing else, for clarity. Include both the apis.json change and the project file changes that occur when the project generator has been run, in the same commit.

Dependencies in the API catalog are specified as properties where the property name is the package name and the value is the version number.

If the version number is set to "project", then a project reference is used.

If the version number is set to "default", then the version number is determined by the project generator, to keep these dependencies in sync for all appropriate packages. This is not permitted for GA releases (i.e. ones with no alpha or beta suffix), as we need a clear record of the dependencies in that case. For example, if the most recent release is 2.3.1 against gRPC 1.7.0, it's fine to make 2.3.2 depend on 1.7.1, but depending on gRPC 1.8.0 would require a new minor version (2.4.0).

Releasing

Releasing consists of five steps:

  • Updating the version number in GitHub (via standard pull requests)
  • Creating a release tag and GitHub release
  • Building and testing
  • Pushing the package to nuget.org
  • Updating the documentation in GitHub (in the gh-pages branch)

Current process

  • After the version number is committed, run tagreleases.sh from the root directory to tag all updated versions.
  • Confirm that you wish to create the given tags.
  • A Jenkins build system will now notice the tags (after a short delay; it checks periodically) and perform the rest of the build and push process automatically.
    • If you wish to perform a manual build, use the command line displayed by tagreleases.sh to run buildrelease.sh, which then displays final instructions for pushing to nuget.org and updating the docs.

Note that tagreleases.sh checks that there are no project references from APIs being released now to APIs that aren't being released. Without this check, it's possible for a released version to depend on unreleased changes.