My first Software Release using GitHub Release
Tags: beginners, opensource, cpp, programming
Published: 2023-11-24 00:50:08

### Software Releases
For the final lab exercise of my Open Source class, we focused on getting our code into the hands of users. Until now, we've done our work publicly on GitHub, with our code readily available for developers to view and contribute to. While this is great for developers, regular users shouldn't have to clone and build my project just to run it. I had to provide a release that can be easily installed and run.

### Package and Release Methods
From class I learned that modern software releases involve package managers and centralized package repositories. Each ecosystem has different specific steps, but the concepts are the same:
- make a reproducible automated build
- use a semantic versioning variant to identify and communicate the version
- use git and tags to log releases in a project history
- use a "package" file that identifies dependencies and what files to include
- upload to a central repository that hosts the release.

### Recommended package and release methods.
There were various approaches recommended depending on our language and ecosystem. My classmates who developed using Node.js were recommended [npm](https://docs.npmjs.com/packages-and-modules/contributing-packages-to-the-registry), and [PyPI](https://packaging.python.org/en/latest/tutorials/packaging-projects/) or [poetry](https://python-poetry.org/) for Python. Since my program is written in C++, I was recommended to look into one of [vcpkg](https://github.com/Microsoft/vcpkg) or [conan](https://conan.io/), but I ultimately did not use either package manager.

#### Why I didn't use a package manager
When doing research for this lab exercise I looked at both vcpkg and conan. Both are package managers that would automate the installation and configuration of my program with its dependencies. 
However, when it came to releasing and sharing my program my options were limited. For example, the central public registry for conan packages is conan-center, but these packages are curated and the process is [very involved](https://docs.conan.io/en/1.17/uploading_packages/bintray/conan_center_guide.html). There was no way conan-center would accept a class project like mine. Alternatively, I could [host a conan package on a public Artifactory](https://docs.conan.io/en/1.53/uploading_packages/using_artifactory.html) repository, but accessing the package requires users to add the repository to their conan remote. This already sounded like too many steps to expect regular users to follow - I already haven't setup any conan remotes, there's no way I could expect regular users to know about conan remotes, let alone have conan installed on their system. After discussing with people online and consulting my instructor, I ultimately decided to do a [GitHub release](https://docs.github.com/en/repositories/releasing-projects-on-github/about-releases). However, in the future I was encouraged to look into using [CMake](https://cmake.org/) or [bazel](https://bazel.build/).

### GitHub Releases
You can create releases on GitHub, using a [Git Tag](https://git-scm.com/book/en/v2/Git-Basics-Tagging) to mark a specific point in the repository's history and making that snapshot available to download and use. To do this, I had to create a git tag of the latest working iteration of my project on my master/main branch of my project:

```
git checkout master
git tag -a v1.0.0 -m "first release"
```

after creating my tag, I had to push the tag to my GitHub repository:

```
git push --follow-tags
```
The `--follow-tags` flag is required to push the annotated tag previously created.

#### Creating GitHub Releases from a Tag - a Visual Crash Course
Once the tags have been pushed to GitHub, I then had to create a release from the tag:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bq4ip4kqsig31crygox3.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7kryue2qnqs0y333mkag.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4c0qmbjf7gjvatak1vru.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6q8k3zcekzgcxvhwtvl.png)

### Modifying my Release
Since git tags are snapshots of entire repositories, my [initial GitHub release](https://github.com/rjwignar/ctil/releases/tag/v1.0.0) contained archives of my source code. This was unacceptable as users only require the final compiled executable. To make my executable available I had to edit my release and drag-and-drop the compiled executable (compressed into a .ZIP archive) into the release:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z778y47fnkw3c02lldg8.png)

After editing my release, the executable was finally available for people to download.

#### Adding user installation instructions.
It's one thing to make a release available, but regular users should also have installation instructions. To this end, I updated my project's README with [installation instructions](https://github.com/rjwignar/ctil#user-installation). In short, to install my program:
- download the ZIP file from the latest release (titled ctil.v.X.Y.Z.zip, where X Y and Z are numbers)
- extract the executable (ctil.exe) from the ZIP file 
- to use the program, open the folder containing ctil.exe in a terminal.

#### Gathering feedback for documentation
To test the usefulness of my instructions, I had a developer friend  try to install my program following only the README. The instructions were fairly clear, but there were a couple sections he missed. To improve the readability, I added subheadings to the instructions. My README is still not perfect, but this is a good start. Ideally, I should gather input from more people to further improve my documentation and program.

### Some regrets
Though version 1.0.0 is out, my program is incomplete. There are missing features and many bugs that require attention. I am also considering using a build system such as [CMake](https://cmake.org/), and moving my development environment to something more platform-agnostic, such as [Visual Studio Code](https://code.visualstudio.com/). Some of these changes involve adding new files or even changing my file structure completely, and will require careful consideration.

I developed this program in Visual Studio 2019/2022 as it was the IDE I was most familiar with for writing C++ programs. Since I wasn't familiar with other build systems at the time, I defaulted to using [MSBuild](https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild?view=vs-2022) (Visual Studio's build system). This was fine for a while, but when it came to adding static testing tools and testing frameworks, I encountered obstacles due to my development environment. And although I was able to find and make my own workarounds, I overall found my development environment unwieldy, and possibly difficult to reproduce. Due to this, I might look into using CMake to build this project.

### Future Changes
I'm hoping to continue my work on ctil even after my Open Source class is finished. Some changes I'd like to make:
- add [command-line option](http://www.catb.org/~esr/writings/taoup/html/ch10s05.html) support to my program
- add conversion support to more Markdown elements
- fix current bugs
- use a new build system
- automate my release process with GitHub Actions
- integrate my linter into my CI workflow
- setup a Dev container for my project using [Dev Containers](https://code.visualstudio.com/docs/devcontainers/create-dev-container) in [GitHub Codespaces](https://docs.github.com/en/codespaces)
- add code coverage analysis to my Google Test setup
- setup a git pre-commit hook to run my source code formatter on any committed changes