diff --git a/public/assets/advanced-github/artifacts.png b/public/assets/advanced-github/artifacts.png new file mode 100644 index 0000000..dd7db5f Binary files /dev/null and b/public/assets/advanced-github/artifacts.png differ diff --git a/public/assets/advanced-github/bctf-actions.png b/public/assets/advanced-github/bctf-actions.png new file mode 100644 index 0000000..307a5ec Binary files /dev/null and b/public/assets/advanced-github/bctf-actions.png differ diff --git a/public/assets/advanced-github/exemplary.png b/public/assets/advanced-github/exemplary.png new file mode 100644 index 0000000..9be3c4f Binary files /dev/null and b/public/assets/advanced-github/exemplary.png differ diff --git a/public/assets/advanced-github/linguist-bar.png b/public/assets/advanced-github/linguist-bar.png new file mode 100644 index 0000000..aaa1082 Binary files /dev/null and b/public/assets/advanced-github/linguist-bar.png differ diff --git a/public/assets/advanced-github/packages-list.png b/public/assets/advanced-github/packages-list.png new file mode 100644 index 0000000..dc4a146 Binary files /dev/null and b/public/assets/advanced-github/packages-list.png differ diff --git a/public/assets/advanced-github/packages.png b/public/assets/advanced-github/packages.png new file mode 100644 index 0000000..39c0ddc Binary files /dev/null and b/public/assets/advanced-github/packages.png differ diff --git a/public/assets/advanced-github/permalink.webm b/public/assets/advanced-github/permalink.webm new file mode 100644 index 0000000..d0f1a43 Binary files /dev/null and b/public/assets/advanced-github/permalink.webm differ diff --git a/public/assets/advanced-github/ubuntu-server-install.png b/public/assets/advanced-github/ubuntu-server-install.png new file mode 100644 index 0000000..f49eaf5 Binary files /dev/null and b/public/assets/advanced-github/ubuntu-server-install.png differ diff --git a/public/assets/advanced-github/vscode.webm b/public/assets/advanced-github/vscode.webm new file mode 100644 index 0000000..a8c5674 Binary files /dev/null and b/public/assets/advanced-github/vscode.webm differ diff --git a/public/assets/cicd-for-university/pr-preview-action.png b/public/assets/cicd-for-university/pr-preview-action.png index 8e01431..c658b52 100644 Binary files a/public/assets/cicd-for-university/pr-preview-action.png and b/public/assets/cicd-for-university/pr-preview-action.png differ diff --git a/src/content/blog/advanced-github.md b/src/content/blog/advanced-github.md new file mode 100644 index 0000000..8056c0f --- /dev/null +++ b/src/content/blog/advanced-github.md @@ -0,0 +1,636 @@ +--- +author: Mark Bundschuh +pubDatetime: 2024-12-16 +title: Advanced GitHub +postSlug: advanced-github +featured: false +draft: false +tags: + - infrastructure + - tools +description: A somewhat comprehensive guide to neat features and tricks on GitHub that you might not know about. +--- + +## Table of contents + +## Introduction + +GitHub is more than just a Git hosting platform. It offers a wide range of features and tools that can help you streamline your development workflow. Some are common like Actions for built in CI, but there is way more beyond even that. I wanted a single comprehensive place to store all the tips and tricks I've learned. Let's learn how to become a GitHub power user. + +For reference, my GitHub username is `mbund`, and I will be using myself as an example GitHub user. + +## Public SSH Keys + +If you've authenticated Git with SSH keys (under [github.com/settings/keys](https://github.com/settings/keys)), they are actually publicly available at `github.com/.keys`. For example, my public keys are available at [github.com/mbund.keys](https://github.com/mbund.keys). Initially, this might sound like a security risk, but they are just public keys so it is safe to share them (though it is good to be aware of this). In my opinion, it is actually really convenient to have them available like this. + +Say you're setting up a server and you want to add your public key to the `authorized_keys` file. You can just run the following command: + +```bash +curl https://github.com/mbund.keys >> ~/.ssh/authorized_keys +``` + +The format that the endpoint hosts is one key per line, exactly like `authorized_keys`. In fact, this is what the Ubuntu Server installer is doing when you select `Github` from `Import SSH identity`. + +Ubuntu server installation on Profile setup screen showing the Import SSH Identity prompt + +(well really it is using the GitHub api [api.github.com/users/mbund/keys](https://api.github.com/users/mbund/keys) and parsing the JSON response, but the effect is the same) + +## Profile Pictures + +GitHub profile pictures are available at `github.com/.png`. For example, my profile picture is available at [github.com/mbund.png](https://github.com/mbund.png). It will redirect to the highest resolution version of the image that GitHub has. + +```html + +``` + +mbund's profile image on GitHub + +## Patches + +When you click on a commit in a repository, you get a "commit url" that look like this: https://github.com/mbund/homelab/commit/e5dc4e462cc8738efd2747336ab559b4ed1e0291. You can turn it into an email patch by appending `.patch` to the end of the url: https://github.com/mbund/homelab/commit/e5dc4e462cc8738efd2747336ab559b4ed1e0291.patch + +This kind of "leaks" the email address of the user who made the commit, but this is just how Git works. Every commit must come with an email address, so even if your email is hidden on GitHub, it might still be in the commit metadata. GitHub does provide you with an email of the form `ID+USERNAME@users.noreply.github.com` which you can use to commit with. I'd recommend [reading the docs](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-personal-account-on-github/managing-email-preferences/setting-your-commit-email-address) on this. + +```diff +From e5dc4e462cc8738efd2747336ab559b4ed1e0291 Mon Sep 17 00:00:00 2001 +From: Mark Bundschuh +Date: Sat, 15 Jun 2024 21:43:01 -0400 +Subject: [PATCH] update tailscale + +--- + system/ingress-nginx-private/templates/tailscale.yaml | 2 +- + .../templates/haproxy-deployment.yaml | 2 +- + system/ingress-nginx-public/templates/tailscale.yaml | 2 +- + system/mailserver/deployment.yaml | 2 +- + system/pihole/values.yaml | 2 +- + terraform/modules/cloudflare/main.tf | 8 ++++---- + 6 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/system/ingress-nginx-private/templates/tailscale.yaml b/system/ingress-nginx-private/templates/tailscale.yaml +index a03fbef..66db303 100644 +--- a/system/ingress-nginx-private/templates/tailscale.yaml ++++ b/system/ingress-nginx-private/templates/tailscale.yaml +@@ -33,7 +33,7 @@ spec: + containers: + - name: tailscale + imagePullPolicy: Always +- image: ghcr.io/tailscale/tailscale:v1.60.0 ++ image: ghcr.io/tailscale/tailscale:v1.68.1 + command: ["/bin/sh"] + args: + - -c +diff --git a/system/ingress-nginx-public/templates/haproxy-deployment.yaml b/system/ingress-nginx-public/templates/haproxy-deployment.yaml +index c10f7de..3ff5998 100644 +``` + +## Permalink and Line Numbers + +In the code view, you can click in the gutter to select a line, then shift click another line to select a range of lines. Notice the url bar update as I perform those actions below. You can then share this url with others to link directly to that line or range of lines. But, if you are on the head of a branch, these links will break if there are changes in the future which shift the lines around. So, it is better to link to a particular commit, making it a [permalink](https://en.wikipedia.org/wiki/Permalink). + +Getting the permalink with the UI can be frustrating, clicking around trying to find the latest commit hash. But, you can actually just press `y` on your keyboard and the url will update with the permalink to the current commit. + + + +You can actually make a selection and press `SHIFT+J` to get the column numbers in the selection as well. + +You can discover more keyboard shortcuts by pressing `?` on most pages, or by reading [the docs](https://docs.github.com/en/get-started/accessibility/keyboard-shortcuts), which is how I found these. + +## Integrated VSCode + +Since Microsoft owns both GitHub and VSCode, it shouldn't be surprising that there is strong integration between the two. You can open a repository in VSCode directly from the browser by pressing `.` on your keyboard. This will replace your tab with a VSCode instance that is connected to the repository. + +Alternatively, you can replace `github.com` with `github.dev` and navigate there yourself, or press `>` to open VSCode in a new tab. + + + +Notice how it respects the line numbers too! + +This lets you edit multiple files at once and make a commit directly from the browser. Though, it has limitations in that you can't run any commands, and many extensions do not work. But, it is still a very powerful feature. + +Somewhat relatedly, you can go to [vscode.dev](https://vscode.dev) without signing in to anything, which is really powerful when you are on a computer you can't install anything on. You can even get the Live Share and then remote into another computer to code with someone else, without installing anything. + +## Linguist and `.gitattributes` + +You know that bar on the right side of the repository that shows the languages used in the repository? + +language distribution bar showing Rust, HTML, TypeScript, SQL, Fluent, Javascript, and Other + +That is powered by [Linguist](https://github.com/github-linguist/linguist), an open-source library that GitHub maintains. It is actually customizable with a `.gitattributes` file in the repository. + +For example, by default, `.sql` files are not detected and shown in the bar as SQL. But, you can add a `.gitattributes` file with the following content to make them show up as SQL: + +```gitattributes +*.sql linguist-detectable=true +``` + +Though, on GitHub this makes it show up as `PLpgSQL` for some reason. But, you can override it to show up as "plain" SQL with: + +```gitattributes +*.sql linguist-detectable=true linguist-language=sql +``` + +If you want the full list of languages that Linguist supports, you can find it [here](https://github.com/github-linguist/linguist/blob/main/lib/linguist/languages.yml). It is updated pretty frequently. + +Let's say there is some file which you don't want to show up as diffable, like a binary file or a lock file. You can add the following to your `.gitattributes` file: + +```gitattributes +Cargo.lock -diff +``` + +Let's say that you vendored a package within your repository, and you want to ignore it from the language statistics altogether since it is a library (also ignoring diffs). You can add the following to your `.gitattributes` file: + +```gitattributes +/my/vendored/lib/ linguist-vendored=true -diff +``` + +You can do some pretty funny things with this, for example I made an [exemplary](https://github.com/mbund/exemplary) repository that runs a GitHub Action every day to update the language statistics to show a random set every day. It is a fun way to show how to manipulate the language bar. + +exemplary GitHub repository showing a random distribution of language in the language bar + +## GitHub API + +Large parts of GitHub are consumable with a JSON api even without an access token. For example, you can get a user's profile information by visiting `api.github.com/users/`. For example, my profile information is available at [api.github.com/users/mbund](https://api.github.com/users/mbund). It can be fun to explore the API and see what you can do with it, and you can use it for test data in your projects. + +## GitHub CLI + +GitHub has an incredible powerful CLI tool called [`gh`](https://github.com/cli/cli). Here are some great commands: + +- `gh auth login`: set up git credentials +- `gh repo create`: create a new repository +- `gh pr checkout`: checkout a pull request locally +- `gh pr merge`: merge a pull request +- `gh run view --log`: view the logs of a GitHub Action run + +I can't stress how many features it has. I'd really suggest checking it out if you haven't already. + +## README Customization + +Here are some README tricks you may have seen out in the wild, and how to do them. + +### Profile README + +If you make a repository the same name as your username, and there is a `README.md` in the root of it, it will show up on your profile page. + +You might have seen some people with fancy profile READMEs. Here are some common ones you might have seen: + +- https://github.com/anuraghazra/github-readme-stats + + + +- https://github.com/lowlighter/metrics + + + +- https://github.com/antonkomarev/github-profile-views-counter + + + +- https://github.com/Platane/snk + + + +### Badges + +Badges are usually from [shields.io](https://shields.io) which let you display any text you like including, but not limitied to: + +- licenses `https://img.shields.io/badge/license-MIT-blue.svg` MIT +- technologies `https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white` TypeScript +- stars `https://img.shields.io/github/stars/mbund/blog` +- last commit `https://img.shields.io/github/last-commit/mbund/blog` + +and [way more](https://shields.io/badges). + +There are lots more sources of badges too. If you append `/badge.svg` to a GitHub Action workflow path, you get the badge of it. For example, + +``` +https://github.com/tokio-rs/tokio/actions/workflows/ci.yml/badge.svg +``` + +produces CI badge which is the status of that workflow. + +Most ecosystems also have ways to get badges. For example, in the Rust ecosystem, you can get a badge from [docs.rs](https://docs.rs) by appending `/badge.svg` to the docs.rs crate path. For example, + +``` +https://docs.rs/tokio/badge.svg +``` + +produces docs build status badge which says if the documentation was able to build successfully. + +In a recent [post of mine](http://localhost:4321/posts/healthscript) I created my own badge service for health checks current health of example.com + +And here's a pro markdown tip for images, since those url lines can get long: + +```markdown +[![Build Status][actions-badge]][actions-url] +[actions-badge]: https://github.com/tokio-rs/tokio/actions/workflows/ci.yml/badge.svg +[actions-url]: https://github.com/tokio-rs/tokio/actions/workflows/ci.yml +``` + +### VHS + +You can use [VHS](https://github.com/charmbracelet/vhs) to programmatically record terminal sessions and embed them in your README. It is a really cool way to show off your CLI projects. + +For example, I created a `.tape` file for [canvas-cli](https://github.com/mbund/canvas-cli) (a tool to interact with [Canvas LMS](https://instructure.com/canvas) from the command line) + +```tape +Output docs/submit.gif + +Require canvas-cli + +Set Shell fish +Set FontSize 32 +Set Width 1500 +Set Height 800 +Set LoopOffset 50% +Set Framerate 24 + +Type "canvas-cli submit upload-test.pdf" Sleep 500ms Enter +Sleep 6s + +# select course +Left # fix rendering issue +Sleep 1s +Down@200ms 5 +Sleep 1s +Up@200ms 5 +Sleep 1s +Enter +Sleep 1s + +# select assignment +Type@200ms "homework 17" Sleep 500ms Enter + +Sleep 8s +``` + +Which generates the following gif: + +submitting an assignment with Canvas Cli + +If I ever update the UI of the CLI, I can just run the `.tape` file again and it will update the gif without me having to rerecord it. The tapes can also be generated in CI for full automation. + +(by the way, you should check out [Charm](https://charm.sh), the creators of VHS and many other cool projects on the CLI) + +### Light/Dark Mode + +You can specify that images should only show up in light or dark mode on GitHub by adding `#gh-dark-mode-only` or `#gh-light-mode-only` to the end of the image url, for example you would do this: + +```html +![GitHub-Mark-Light](https://user-images.githubusercontent.com/3369400/139447912-e0f43f33-6d9f-45f8-be46-2df5bbc91289.png#gh-dark-mode-only) +![GitHub-Mark-Dark](https://user-images.githubusercontent.com/3369400/139448065-39a229ba-4b06-434b-bc67-616e2ed80c8f.png#gh-light-mode-only) +``` + +GitHub logo on light and dark backgrounds in an open issue + +### Allowed HTML + +Basic stuff like `

`, ``, `` etc. are allowed as expected. And here are your options for alignment (since there is no CSS): + +```html +

+

center

+
+
+

left

+
+
+

right

+
+``` + +
+

center

+
+
+

left

+
+
+

right

+
+ +### SVGs + +While you can't embed arbitrary HTML in GitHub's READMEs, you can embed SVGs. This can be used to create some of the effects you might have thought were only possible with HTML and CSS. + +animated Mark's Homelab text with many technology logos + +### Live Dashboards + +If you want live data, like an `