Last month I contributed to an Open Source project: CLI for Microsoft 365, which is driven by the Microsoft 365 Patterns and Practices initiative. I did that both because I love using CLI’s and because I love not reinventing wheels. I can’t count the number of situations where I benefited from the Patterns and Practices initiative. Minor sidenote: it’s probably also because Albert-Jan Schot tweets every week (!) about x good first issues and I was curious what kind of issues would fall in that category.
Anyway, I’m publishing this post to pay it forward. Contributing to open source is not difficult, and wouldn’t it be cool (and benefit us all) if every developer in the world would spend some time each year to contribute. Maybe as a holiday season present to the community. Here’s my two cents:
Table of Contents
- Getting started
- My development environment
- Step 1: Forking and cloning
- Step 2: Configure upstream and create branch
- Step 3: Start hacking
- Step 4: Creating a pull request
- Parting words
The first thing I did was read up on the contribution guidelines of the CLI for Microsoft 365. It helps to know how the contributors want to work together, things about how to write your code, so that it will adhere to central ideas. What things to take note of, like adding documentation pages, unit tests and taking care of a 100% code coverage. But also how to deliver the changes back on a gold platter when creating your pull request back to the project repository.
Next, I chose a good first issue to get started. I picked something that didn’t look too hard, because I wanted to get the lay of the lands first. And last but not least, I offered my help in a comment, just to make sure that my contribution would be noticed. I didn’t want to start working on something that by accident was already under development by someone else. Or to start working on something that needed some more discussion first.
Although everyone works from home: Open Source is teamwork nonetheless. You need good discussions about specifications upfront, to create good and helpful functionality later.
My development environment
After reading up and chatting up, I got my first issue assigned. This all only took a few hours by the way. The next hurdle was my development environment. I often use docker to separate dependencies between projects, so my environment of choice is as follows:
- Visual Studio Code
- Remote Container Extension for VS Code
The CLI team has a fully configured docker image available for you, which installs all the dependendies you need. This is especially great because the CLI team also added a MkDocs documentation site. MkDocs (I’ve blogged about that here) uses python and a load of dependencies. All those dependencies are available within the docker image. So if you want the easiest experience, not clutter your own system, and docker doesn’t scare you, it’s really just best to use it.
Step 1: Forking and cloning
The first step is to fork the repo and copy the git url. Now, you could continue like this:
# Find a nice directory on your filesystem and... git clone https://github.com/martinlingstuyl/cli-microsoft365 # Clone the repo cd cli-microsoft365 # Enter the directory code . # Open the directory in VS Code
…but I prefer another route:
- Open a brand new VS code instance
- Open the command palette using
Ctrl + Shift + P.
- Use the remote container extension command Clone repository in container volume.
This clones the repository in an isolated named volume and builds/starts the docker container. To clone a repo in this way has some performance benefits, plus I find it easier to fire up a remote container this way. Less clicks and file management, and everything from within my VS Code context. It’s also easier to clean up afterwards: simply delete the volume from within VS Code and you’re done. You can read about it here.
If all is well, you’ll end up with VS Code running the cli project in a remote container.
Step 2: Configure upstream and create branch
After the docker image is built and the remote container has opened in VS Code, open a terminal and execute the following script:
# Configure an upstream so you can sync changes with the source repo git remote add upstream https://github.com/pnp/cli-microsoft365.git # Create a branch for your issue or feature and check it out git checkout -b command-xyz
Configuring an upstream is necessary later on when creating a pull request. Read more here.
Step 3: Start hacking
This is the part where the actual work begins. Studying some existing commands and the available npm scripts in
package.json is a good first move.
I found myself regularly executing these:
npm run build # Running a build npm run test # Running unit tests npm link # Setup the package so it can be used from the commandline # Running the documentation site to see your changes cd ./docs mkdocs serve
I found the project setup straightforward and therefore most of the work was easy going. The most important thing is to make sure to check the work of others and keep your own work neat and as limited as possible.
A few things you might run into:
Unit tests and 100% code coverage
There is a high standard for unit tests in the project, you need to make sure you achieve a 100% code coverage. That means that every code path (for example
else statements) needs to be checked using a test. Executing
npm run test will show the code coverage and help you to narrow down on parts that aren’t covered by tests.
Sample data in unit tests.
You’ll find you need a lot of sample data when creating unit tests. I simply used the sample data from the Microsoft documentation site for the Graph endpoints I was consuming. This saved me a lot of time. Another route (when calling Microsoft Graph) is to use the sample data returning in the Graph Explorer when you’re not signed in.For example...
Running tests takes a long time
Running all the tests takes a long time to complete. To only run my own tests, I temporarily added the following npm script to the
package.json file to make sure only my own spec-file was tested.:
"test:mytest": "mocha \"dist/**/my-command.spec.js\" --timeout 10000"`
But make sure you don’t commit it with the other changes.
Exception while running tests
I sometimes ran into the following exception when executing
npm run test:
TypeError: Suite argument "title" must be a string. Received type "undefined"
The solution for me was to execute
npm run clean and rebuild the package:
Exception while executing commands
npm link you can execute the
m365 commands in the project using the terminal. I often did this to test my own commandlets. Sometimes I would run into the following exception:
zsh: permission denied: m365
I’m not sure what the reason for this is, but to fix it I uninstalled the package and relinked it:
npm uninstall pnp/cli-microsoft365 -g npm link
Step 4: Creating a pull request
When you think your feature or issue is ready, it’s time to submit the pull request. To prepare for a good pull request, you need to sync your fork with the main repo to get the changes that where added while you where hacking away on your own fork. If you’ve configured your upstream correctly, the following script will do that for you:
# Sync and rebase main branch to get the latest changes git fetch upstream git checkout main git pull --rebase upstream main # Rebase feature branch to get the latest changes git checkout command-xyz git rebase main
You will find the more complete checklist here though.
Creating the pull request in question is easy using the github site, just make sure you reference your feature branch and the main branch of the central repository.
In conclusion I found it a great way to contribute. “Sharing is caring”, but it also gave me back something: learning from the work of others. I hope my words will cheer you on or help you on the road. And don’t forget to read-up and chat-up before starting.
- Contributing to CLI for Microsoft 365
- Getting started contributing
- Submitting a PR
- Remote containers extension
- Cloning in remote container volumes
- Configuring an upstream with forks in GitHub
cli microsoft365 docker contributing mkdocs
Support me by sharing this
When contributing to the Microsoft 365 CLI Open Source project you need to write a lot of unit tests. I wrote down some tips and tricks to get you up and running.Read more
MkDocs is a great tool to create straightforward documentation sites. It's 1 of 2 static site generators I've recently worked with.Read more
When using SPFx Library Components we are instructed to execute npm link when debugging our webparts. But what if we are using dev containers?Read more
Thanks for reading
Thanks for reading my blog, I hope you got what you came for. Blogs of others have been super important during my work. This site is me returning the favor. If you read anything you do not understand because I failed to clarify it enough, please drop me a post using my socials or the contact form.
Microsoft 365 Architect
I4-YOU Business Solutions b.v.