Procedure for creating a new repository
About this document
This document describes the recipe to create a new GitHub repository. It's meant for class libraries.
Introduction
The strict following of this procedure is required in order to maintain consistency and coherence throughout the repositories, along with taking advantage of the build tools, testing and publishing automation. If in doubt please ask one of the senior team members.
Creating the repository in GitHub
- This is basically clicking the create new repository button in GitHub. Note: The class libraries repositories are usually named with the prefix "nanoFramework.namespace" most of the remaining repositories are "nf-some-relevant-name-here".
- As we are following the GitFlow branching model two branches must be created:
main
anddevelop
. - Make sure to create an empty readme.md to make it easier to fork and clone the new repo.
Adjust the repository settings (part 1)
- Go to the repository Settings and move into Options.
- In theFeatures section disable Wikis, Issues and Projects.
- On the Pull Requests section disable Allow merge commits. We prefer to have tidy merges on PRs without having to bother contributors to squash commits.
- Also there, disable merge commits. We prefer a straight history line.
- Another tweak there: at allow squash merging, set the default message to
Pull request title
. - Move into Branches and set
main
as the default branch.
Setup Sonarcloud project
For class libraries projects a Sonarcloud project has to be setup in order to run and process the project analysis.
- Sign-in to Sonarcloud and create a new project.
- On the repository list choose the corresponding name.
- Choose "previous code" as the metrics analysis for new code.
- OK to leave the rest with their defaults.
Setup Azure DevOps
Build Pipeline
- Open a new browser window on which you are signed in to GitHub as
nfbot
. - On the repo Settings, navigate to "GitHub Apps".
- Click "Configure" button for Azure Pipelines.
- The next step will take you to the Azure DevOps website.
- Click on "Create New Project".
- Name the project following the GitHub repo name. Select Public for visibility option.
- After the project is created a list with GitHub repositories shows. Select the repository that has been just created.
- The next step asks for the Pipeline configuration. Choose "Starter Pipeline" to get the build running and allow configuring the pipeline. The next steps will show the minimal yaml.
- Click on "Variables" and add the following ones.
- Add
DiscordWebhook
with a value taken from the Azure webhook of the "build-monitor" channel in our Discord server. Make sure that the variable is set tosecret
by clicking on the appropriate option. - Add another variable
GitHubToken
with a value taken from the nfbot personal tokens in GitHub. Make sure that the variable is set tosecret
by clicking on the padlock icon. - Add another variable
NbgvParameters
, leave it empty and check "Let users override this value when running this pipeline". - Add another variable
StartReleaseCandidate
, set the content tofalse
and check "Let users override this value when running this pipeline". - Add another variable
UPDATE_DEPENDENTS
, set the content tofalse
and check "Let users override this value when running this pipeline". - Click the "Save" button on the Variables pop-up (it will take you back to the pipeline yaml).
- Cline the "Save" button at the top right and go through the commit message.
- Navigate back to the Pipeline, select it and click "Edit" (at the top right). Then click on the 3 vertical dots (again at the top right) and then "Triggers".
- Make sure that the option to override YAML is not checked for "Continuous integration". Uncheck the same option for "Pull request validation" and check the "Make secrets available to builds of forks".
- Unckeck "Shallow fetch" in YAML tab.
- Click "Save" in the toolbar (NOT "Save & Queue").
- Go to the
General Project
project and navigate to Project Settings - Service Connections. - Open each of the service connections there, click on the 3 vertical dots (again at the top right) and then "Security". Scroll down to "Project permissions", click on the + icon at the right hand side and select the newlly created project. This will add a permission to use this shared service connection.
- Navigate to the
Library
section (underPipelines
) and click on the plus sign to add a newVariable group
namedsign-client-credentials
. - Add the following variables, all set to secret, with the values comming from the .NET Foundation signing service. Variables are
SignClientId
,SignClientSecret
,SignKeyVaultCertificate
,SignKeyVaultUrl
andSignTenantId
. Make sure that all the variables are set tosecret
by clicking on the appropriate option. - Go back to the pipelines view and with the current pipeline selected, click on the ellipsis icon and then on "Status badge". Copy the markdown code that shows on the pop-up. This will be required to add the correct build badges in the repo readme in a moment.
Bootstrap pipeline
- Go to the project pipelines page and click "New Pipeline".
- Choose GitHub, select the repository, in configuration step select the option "Existing Azure Pipelines YAML file" and in the path, the azure-bootstrap.yml.
- Click on "Variables" and add the following.
- Add
AZURE_DEVOPS_PAT
with the PAT for ADO access. Make sure that the variable is set tosecret
by clicking on the appropriate option. - Click the "Save" button on the Variables pop-up (it will take you back to the pipeline yaml).
- Cline the "Save" button at the top right and go through the commit message.
- Navigate back to the Pipeline, select it and click "Edit" (at the top right). Then click on the 3 vertical dots (again at the top right) and then "Triggers".
- Rename the pipeline to match the project name ending in bootstap (like in "nanoFramework.Json bootstrap").
- Click "Save" in the toolbar (NOT "Save & Queue").
Prepare the initial commit
- Fork the repo into your preferred GutHub account and clone it locally.
- The best option is to copy/paste from an existing repo, so you're more efficient doing just that. Mind the name changes tough! Grab the following files:
- .gitignore (no changes required)
- azure-pipelines.yml
- LICENSE.md (no changes required)
- README.md
- version.json
- NuGet.Config
- assets\readme.txt
- assets\nf-logo.png
- Open "azure-pipelines.yml"
- Rename the
nugetPackageName
variable with the new name (mind the nanoframework prefix). - Rename the
repoName
variable with the repo name. - Rename the
sourceFileName
parameter with the equivalent name. It's probably wise to wait for the first successful build of the class library and then get back here with the correct name for the assembly declaration source file. - Rename the
sonarCloudProject
variable with the project key from the Sonarcloud project. - If there are class libraries that depend on this one, copy the "update dependencies" job from CorLib "azure-pipelines.yml". If there aren't just skip this step.
- Rename the
- Open "version.json" and set the version to the appropriate one. Make sure to follow our version number guidelines. In doubt please ask one of the senior team members.
- Open "README.md"
- Rename the class library name occurrences with the new name.
- Rename the package name for the NuGet badges.
- Replace the build status badges with the ones that you've copied from Azure DevOps. They'll be the same until there is a second pipeline for the master branch.
- Create a folder at the root level with the name of the new class library.
- Add to the VS Solution the class library project. Again it's better to follow an existing one and ask in doubt.
- Make sure you are following the naming pattern.
- Make sure you copy the
key.snk
from the initial repo (or from the CorLib repo). DO NOT create a new one.
- Rename, edit and adjust as required the "nuspec" files to create the NuGet packages.
- Edit the "readme.txt" inside the
assets
folder and rename the repository name. - Still on"azure-pipelines.yml" and only if there are class libraries that depend on this one.
- Adjust the
repositoriesToUpdate
list with the repo names of the class libraries that depend on this new one.
- Adjust the
- Create the .github folder with the workflows directory and the github actions yaml files inside.
- Open the yaml files of the github actions and adjust the solution name.
Adjust the repository settings (part 2)
- Go to the repository settings in GitHub and move into Branches.
- Go to the rule for "develop" branch and change the following:
- Enable "Require pull request reviews before merging"
- Enable "Require status checks to pass before merging" with the options:
- "Require branches to be up to date before merging"
- "Status checks: nanoframework.azure-devops-project-name"
- "Status checks: license/cla" (for main branch)
Update the dependency upwards
As a minimum, the new class library depends on mscorlib. If that's the only dependency, edit the azure-pipelines.yml
file there and add this new repo to the repositoriesToUpdate
list.
Now, if it depends on others, you have to figure out which one of those is at the end of the dependency chain and add this new repo to that azure-pipelines.yml
file. For example, System.Device.Gpio
depends on CoreLibrary
and Runtime.Events
(which, in turn, depends on CoreLibrary
). Updating it's dependencies has to the triggered at Runtime.Events
not on CoreLibrary
because of the chained dependency.
Add the class library to the documentation project
If this class library has documentation that has to be published as part of nanoFramework documentation (which is most likely) it needs to be referenced in the documentation project.
- Edit the documentation repo
azure-pipelines.yml
and add entries for this new repo at steps:clone
,restore
andbuild
. Just follow one of the others already there. - Edit the class library documentation document and add an entry for the new class library in the appropriate table, following the pattern and format being used there.