-->

dev git, github

These days it’s essential to know how to clone a GitHub repository as GitHub is the de-facto standard for source code repositories. According to this source, GitHub has 100 million users. If you follow tech blogs, such as this one, you will be asked to clone a GitHub repository to follow along. In this post, you will look into all the ways to download code from GitHub to quickly get the source code you need without setting it up on the spot.

You can pick any public repository on GitHub to follow along. In this example, I will choose one from trending repositories: Awesome Security Hardening.

Method 1: Download Zip File

If you don’t have anything on your computer, the easiest way to get the latest code from a GitHub repository is the Download Zip option.

When you land on the repository page, you will see a green button that says Code in the middle:

Repository page showing Code button

Click the Code button and click the Download ZIP button in the dialog:

A dialog box is displayed after clicking the Code button, showing the Download ZIP button.

Your download should start automatically.

This method works even if you’re not logged in to GitHub.

Locate the downloaded file and extract:

The downloaded zip file is extracted to a folder and contents of the folder are shown.

This example contains a single README.md file, as shown in the screenshot above.

Method 2: HTTPS

You need to have Git CLI installed on your computer for this method.

Click the Code button and copy the link shown in the HTTPS tab:

A dialog box is displayed after clicking the Code button, showing the HTTPS tab and the link copied to the clipboard by clicking the Copy button next to the link

In a terminal, navigate to the parent folder where you want to save the source code and run the following command:

git clone https://github.com/decalage2/awesome-security-hardening.git

You should see the results that look like this:

A terminal window showing successful results of a git clone command

Method 3: SSH

You need to have Git CLI installed on your computer for this method. Also, you have to be logged in to your GitHub account and have created and set up an SSH key. See the GitHub support page to set up an SSH key.

As you may have noticed in the screenshots of Method 1 and Method 2, the SSH method is not visible when you are not logged in to your GitHub account.

First, log in to your account for the SSH method to work.

Then, visit the URL of the repository and click the Code button and copy the SSH link:

Code button clicked and dialog showing SSH tab

In the terminal, run the following code:

git clone git@github.com:decalage2/awesome-security-hardening.git

The output should look like this:

Terminal window showing successful output of git clone command using SSH method

Method 4: GitHub CLI

If you are using GitHub frequently, I’d recommend installing GitHub CLI.

Visit cli.github.com and click the Download button on the screen:

Landing page of GitHub CLI

If you use Windows or Linux, GitHub will automatically show you the relevant download link.

If you are using macOS, I’d recommend using brew to install. Brew is a package manager for macOS and Linux, and you can install it by going to brew.sh and running the installation script.

Then you can install GitHub CLI by simply running the following code in your terminal:

brew install gh

After you’ve installed the CLI, run the following command to confirm it’s installed successfully:

gh version

You should see something like this:

Terminal window showing output of gh version command

Once you have the CLI installed, you have to log in to your GitHub by running

gh auth login

Select the options that match your environment and circumstances using the interactive CLI. For example, in the example below, I selected GitHub.com, HTTPS and Yes to log in with GitHub credentials and selected Login with a web browser:

Terminal window showing output of gh auth login command. Selected GitHub.com, HTTPS, GitHub credentials and login with a web browser options

Then, open GitHub.com in your default browser and enter the one-time code displayed on your terminal.

GitHub webpage asking for a Device Activation code

Then accept the authorization request for the CLI to access your GitHub account:

Authorize GitHub CLI page asking for permissions for CLI to access GitHub

After the CLI has been installed and authorized, cloning a GitHub repository is very easy. Run the following command to clone the example repository:

gh repo clone decalage2/awesome-security-hardening

and you should see the successful results:

Terminal window showing successful output of gh repo clone command

Conclusion

You walked through all four methods to clone a GitHub repository in this article. Having the ability to clone a repository on GitHub is very important for a developer. So I hope you enjoyed this article and spent some time setting up your environment to be a more productive developer.

Resources

dev excel

Spreadsheets are great tools. They are user interface and database combined in one application and have been infinitely helpful for ages. In this post, we are going to look into a handy NuGet package called ClosedXML to create and manipulate Excel spreadsheets by using a CLI demo application.

Demo Use Case

As the energy crisis is getting worse, electricity prices are skyrocketing everywhere. So I decided to create a spreadsheet to log daily electricity costs programmatically. This generally is possible if you have a Smart Meter and can get daily costs from your supplier. Either way, the main objective is to demonstrate using .NET and ClosedXML NuGet package.

The final spreadsheet will look like this:

Spreadsheet showing daily electricity costs and monthly total cost

Usage

The project is a CLI project created using the dotnet tool and CliFx. You can also find the detailed blog post about creating your own CLIs published on this blog.

After you’ve cloned the repository, publish the application as a dotnet tool.

dotnet pack
dotnet tool install --global --add-source ./ElectricityCost.CLI/nupkg/ ElectricityCost.CLI

Then you can use it anywhere on your machine.

For example, to create a new spreadsheet from the built-in template, you can run this:

ec closedxml template new --path ElectricityCosts.xlsx

And you can add new costs by providing the day of the month and the cost value:

ec closedxml add --path ElectricityCosts.xlsx --day 2 --cost 3.44

Implementation: Using CloseXML - An easier alternative to OpenXML SDK

ClosedXML is a wrapper around OpenXML that makes Excel spreadsheet manipulation a breeze.

When working with a spreadsheet, you often want to address the cells by row and columns as you would typically do in a table and read/write data into it. ClosedXML allows us to do precisely that.

using ClosedXML.Excel;

using (var workbook = new XLWorkbook())
{
    var worksheet = workbook.Worksheets.Add("ClosedXMLDemo");
    worksheet.Cell("A1").Value = "Hello World!";
    workbook.SaveAs("Sample1.xlsx");
}

The code snippet above creates a new Excel file and saves it in the Sample.xlsx file. SaveAs might sound like it only handles existing files, but it is called to create new files.

Working on existing spreadsheets is also relatively straightforward. Pass the file’s path to the XLWorkbook constructor, and you can find the spreadsheet by a simple LINQ query.

using (var workbook = new XLWorkbook("Sample1.xlsx") )
{
    var worksheet = workbook.Worksheets.First(ws => ws.Name == "ClosedXMLDemo");
    Console.WriteLine(worksheet.Cell("A1").Value);
}

And setting formulas is also as simple as setting the value. The following snippet shows a formula to calculate the sum of daily costs:

worksheet.Cell("E1").FormulaA1 = $"=SUM(B2:B{numberOfDaysInCurrentMonth + 1})";

Managing the styles is also quite intuitive:

var rngSubTotals = rngTable.Range("D2:E3");
rngSubTotals.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
rngSubTotals.Style.Font.Bold = true;
rngSubTotals.Style.Font.FontSize = 20;
rngSubTotals.Style.Font.FontColor = XLColor.Red;
rngSubTotals.Style.NumberFormat.Format = $"{CURRENCY_SYMBOL} #,##0.00";

For the sake of brevity, I’m not going to put all the code in this post. So, please visit the GitHub repo and play around with the code.

Conclusion

In this post, we looked into using a very intuitive and powerful NuGet package: ClosedXML. However, dealing with OpenXML directly can be overwhelming so having the ability to manipulate Excel spreadsheets with a straightforward tool is handy.

Resources

docker podcast, downloader

Versioning is an important and one of the rather tricky aspects of software development. Simply put, versioning assigns a unique number that identifies a specific package or release. This post will look into a popular versioning method called Semantic Versioning.

What is Semantic Versioning?

Semantic Versioning is a popular versioning scheme that mainly uses a three-part version number. The version number is in the following format (there are pre-release versions as well, which we will look into in detail later):

MAJOR.MINOR.PATCH

For example, if the version number is 2.3.54, the individual parts would mean:

  • 2: Major version
  • 3: Minor version
  • 54: Patch version

The rule of thumb when it comes to incrementing these numbers is:

Major version

The major version number is incremented when you make incompatible changes.

Examples:

  • You removed an entire public class from a NuGet package

  • You changed the parameters that the API endpoint accepts

Minor version

The minor version is incremented when you add new functionality in a backwards-compatible manner.

Examples:

  • You add a new endpoint to a public API

  • You add a new parameter to a method with a default value so that old consumer can still call the method without breaking it.

Patch version

The Patch version is incremented when making backwards-compatible fixes.

Examples:

  • You fixed a bug without making backwards-incompatible changes

Pre-releases

In addition to the major, minor and patch versions, we may want to use pre-release versions. This would indicate that the product is not finalized. Examples of pre-release versions:

2.0.0-alpha

2.0.0-alpha.1

2.0.0-beta

2.0.0-beta.1

2.0.0-beta.2

2.0.0-rc.1

All the examples above are pre-release versions and are ordered from the lowest precedence to the highest one.

Please note semantic versioning has no knowledge of the words “alpha”, “beta”, or “rc”. The comparison is purely made by alphabetical order for non-numeric versions.

Build metadata

In addition to all the release and pre-release versions, we can also use extra metadata by using a plus sign (+) as a separator. This part is not used in precedence calculations and has informational purposes only. The metadata that follows the plus sign can be a series of dot-separated identifier lists.

For example, a version number with build metadata could look like this:

2.1.5+20220531 // Append the date of the release

1.8-beta+sha.a4b5d6 // Append a hash value of the package

Refactoring

How about refactoring? It’s not a significant breaking change, and you don’t add new functionality. Also, it doesn’t count as bug fixes. It might help prevent bugs from being introduced in the future, but it doesn’t strictly count as fixing anything.

We can find the answer in the Semantic Versioning specs:

Patch version Z (x.y.Z x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. A bug fix is defined as an internal change that fixes incorrect behavior.

So if you change the code for whatever reason, you must at least increment the patch version to maintain the uniqueness of the package/release.

Front-end Versioning

A common question and debated issue is how to version front-ends. The Semantic Versioning specification is all about “API changes”. API in this context can refer to a HTTP API or a package (NuGet, npm, Maven etc.).

Front-ends are consumed by end-users, and they are not consumed by other software.

By saying not consumed by other software, I’m not counting the web scrapers. When you develop a front-end page, you don’t make a contract with an external tool whose goal is to scrape data from your page. Most likely, it happens without your consent. Therefore, if you make a change in your markup that breaks web scrapers, it doesn’t constitute breaking change in an API.

Defining a “breaking change” in a front-end is not easy. For example, if you move functionality to another page, it might be seen as a breaking change as some users might fail to find the new location of the functionality. Does this mean that you should increment the major version? If you did, what would that mean to the end-users? They still need to use the application/website like before. When interacting with actual human users, version numbers don’t mean much.

Users don’t care about your versions

The only exception I can think of is a complete project overhaul. If everything changes so drastically, you may choose to refer to it as version 2.0 of your application.

Other than that, I’d argue the best way to handle changes in a user-facing application is by leveraging changelogs.

When a user logs in, you can display them a nice little pop-up and briefly explain the key things that changed. Some more complicated changes might need some interactive walkthroughs etc. The main point is, that a user doesn’t want to or need to know that you deployed 2.10.24 version of your application. So show them how it affects their experience and leave the technical details out.

Conclusion

Semantic Versioning is a very popular versioning scheme as it’s simple and flexible. Some aspects are debatable whether or not it should be used, such as front-end versioning, but this doesn’t mean that it does a good job most of the time. We also discussed how to handle versioning in user-facing applications.

Resources