diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..ea1b6fc --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,22 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node +{ + "name": "Node.js & TypeScript", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm", + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "npm install", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + "remoteUser": "root" +} diff --git a/package.json b/package.json index 86d3515..8631462 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "private": true, "scripts": { - "dev": "vite dev", + "dev": "vite dev --host", "build": "vite build && npm run build:pagefind", "preview": "npm run preview:pagefind && vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", diff --git a/src/cv.pdf b/src/cv.pdf index e3fc23c..667af62 100755 Binary files a/src/cv.pdf and b/src/cv.pdf differ diff --git a/src/routes/logo.avif b/src/routes/logo.avif index 6a433cc..36bf3a0 100644 Binary files a/src/routes/logo.avif and b/src/routes/logo.avif differ diff --git a/src/routes/posts/2024.05.27.adding-single-click-dev-environment-links-to-your-open-sourc.md b/src/routes/posts/2024.05.27.adding-single-click-dev-environment-links-to-your-open-sourc.md new file mode 100644 index 0000000..f095d70 --- /dev/null +++ b/src/routes/posts/2024.05.27.adding-single-click-dev-environment-links-to-your-open-sourc.md @@ -0,0 +1,117 @@ +--- +title: 'Adding single click dev environment links to your open source project for easy contributions' +date: 2024-05-27T05:10:06Z +description: 'Blog post description here' +--- + +[I have been using DevContainers](/2023.02.10.why-use-devcontainer/) a lot. If +you haven't heard about them, it's a standard for defining development +environements using container technologies. The idea is pretty simple: you +define a base container for your development environment --which can be a +special DevContainer one, or any regular old container-- along with any service +containers you need. Whenever you or anyone else needs a new development +environment, their development environment grabs and runs these docker +containers, and runs any commands you defined in the configuration to set things +up. + +This comes with many benefits: +- Assuming you deploy with containers, your development environment can more + closely match your production environment. +- There are no "works on my machine" issues, everyone has the same development + environment. +- If anything goes wrong with your development environment, instead of trying to + figure out what happened, you can delete it and start over in seconds. +- You were in the middle of something, and an urgent bug came up? Instead of + trying to stash your work and clean up your environment, leave it where it is + and launch another fresh development environment and get to work. +- New contributors to your open source project, or new hires can start + developing immediately without having to set up anything, beyond installing + Docker. + +The last point here is the one I want to focus on in this blog post. Especially +with open source projects, one of the biggest barriers to contribution is that +it can be hard to install and set up everything you need to contribute to a +project. Especially if you were trying to fix or add something small, it can be +harder to set up the development environment than it is to actually develop +whatever you were actually trying to do. The same issue applies for companies. +Onboarding new employees is hard. Writing good onboarding documentation and +keeping it up to date takes a lot of work. But without good documentation, new +hires have to keep bugging experienced developers so they can start working. +This slows down how soon new hires can start doing productive work, takes up +time of experienced devs, and leaves everyone frustrated. + +If I have sold you on DevContainers, check out [my previous blog post](/2023.02.10.why-use-devcontainer/) +on the topic on how to get started or +[VSCode docs](https://code.visualstudio.com/docs/devcontainers/containers) +(note: DevContainers are not exclusive to VSCode, support is being added to +JetBrains products, and a CLI implementation is available as well). +Once you have your DevContainers set up though, you get an amazing opportunity to make contributions or development even easier. +Enter cloud development environments. + +DevContainer support is built into [Github Codespaces](https://github.com/features/codespaces) and [CodeSandbox](https://codesandbox.io/). +These projects allow you to spin up machines in the cloud for development, and work on it through a web interface. +Combined with DevContainers, you can click one button to get a fully-fledged development environment in your web browser within seconds. +Along with these, [DevPod](https://devpod.sh) is an open source solution that you can install on your own machine, +and use with a local Docker install, remote VMs, or one of their many supported providers like AWS or Azure or DigitalOcean. +You can take advantage of this yourself by just having these services/tools clone your repository, +but we can make it even better and help newcomers by adding links to these services. + +![Screenshot of a page with the headline Contributing, and the text: Want to start hacking on this quickly? Click one of these links to get started right now!](/img/codespaces-devpod-codesandbox.avif) + +To do so, simply add the following links to your Readme, replacing `` and +`` with your own username and repository. Note that besides Github +Codespaces, these are not restricted to Github and +can be used with other forge services like [Gitlab](https://about.gitlab.com) or [Codeberg](https://codeberg.org). + + +```md +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new//) +[![Open in DevPod](https://devpod.sh/assets/open-in-devpod.svg)](https://devpod.sh/open#https://github.com//) +[![Open in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/devbox/github//) +``` + +Having these links in your Readme is nice, but what if we went one step further? +We could use these tools to make PR reviews easier too. You can click one button +on Github or your favorite forge to see the changes in a PR, wouldn't it be +great if you can click one button to launch a fresh development environment with +that PR? It would be, and we can do this! + +To make this happen, I wrote a Github Actions workflow to post a comment to PRs +with the appropriate links. Let's see what that workflow looks like: + +```yml +on: pull_request + +permissions: + pull-requests: write + +jobs: + comment_click_dev: + runs-on: ubuntu-latest + name: Comment Cloud Dev Buttons + steps: + - name: Comment PR + uses: thollander/actions-comment-pull-request@v2 + with: + message: | + Click links below to open this PR in a dev environment: + + [![Open PR in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new///tree/${{github.head_ref}}) + [![Open PR in DevPod](https://devpod.sh/assets/open-in-devpod.svg)](https://devpod.sh/open#https://github.com//@${{github.head_ref}}) + [![Open PR in CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://githubbox.com///tree/${{github.head_ref}}) + comment_tag: comment_click_dev +``` + +This workflow uses [this cool action by Térence Hollander](https://github.com/marketplace/actions/comment-pull-request) +to post a comment to the PR from a workflow. +Like the Readme example, replace the `` and `` with your username and repository. + +![Screenshot of Github PR comment by github actions bot. The comment has 3 buttons for Codespaces, DevPod, and CodeSandbox. Text above the buttons reads: Click links below to open this PR in a dev environment](/img/codespaces-devpod-codesandbox.avif) + +These work great. Whenever you're reviewing a PR, if you want to run the code or +use a more comfortable environment than Github's changes view, you can click +these buttons and get the PR in a new development environment, without having to +stash or discard anything you were already working on. + +The only caveat with these links is that I couldn't figure out how to make it work for CodeSandbox without going through the `githubbox.com` URL. +This URL seems to be owned by CodeSandbox from what I gather so it's not dangerous or anything, but it limits it to repositories on Github only. diff --git a/src/routes/profile.avif b/src/routes/profile.avif index a204b0e..5030a6c 100644 Binary files a/src/routes/profile.avif and b/src/routes/profile.avif differ diff --git a/static/android-chrome-192x192.png b/static/android-chrome-192x192.png index d8ca2b9..5630cea 100644 Binary files a/static/android-chrome-192x192.png and b/static/android-chrome-192x192.png differ diff --git a/static/android-chrome-512x512.png b/static/android-chrome-512x512.png index 6d71b66..ef9875e 100644 Binary files a/static/android-chrome-512x512.png and b/static/android-chrome-512x512.png differ diff --git a/static/apple-touch-icon.png b/static/apple-touch-icon.png index 70bf05c..9d13f2a 100644 Binary files a/static/apple-touch-icon.png and b/static/apple-touch-icon.png differ diff --git a/static/favicon-16x16.png b/static/favicon-16x16.png index b6d7f02..a1041f9 100644 Binary files a/static/favicon-16x16.png and b/static/favicon-16x16.png differ diff --git a/static/favicon-32x32.png b/static/favicon-32x32.png index db4c896..72860ab 100644 Binary files a/static/favicon-32x32.png and b/static/favicon-32x32.png differ diff --git a/static/favicon.png b/static/favicon.png index 439ade8..02d7b0d 100644 Binary files a/static/favicon.png and b/static/favicon.png differ diff --git a/static/img/2022-03-29-00-16-13.png b/static/img/2022-03-29-00-16-13.png index 31121d1..7c09c2d 100644 Binary files a/static/img/2022-03-29-00-16-13.png and b/static/img/2022-03-29-00-16-13.png differ diff --git a/static/img/2022-03-29-00-17-38.png b/static/img/2022-03-29-00-17-38.png index 0bbe279..1a787a3 100644 Binary files a/static/img/2022-03-29-00-17-38.png and b/static/img/2022-03-29-00-17-38.png differ diff --git a/static/img/2022-03-29-00-20-48.png b/static/img/2022-03-29-00-20-48.png index 81525f7..7aeff78 100644 Binary files a/static/img/2022-03-29-00-20-48.png and b/static/img/2022-03-29-00-20-48.png differ diff --git a/static/img/2022-03-29-00-22-48.png b/static/img/2022-03-29-00-22-48.png index 546db8f..69c1bc1 100644 Binary files a/static/img/2022-03-29-00-22-48.png and b/static/img/2022-03-29-00-22-48.png differ diff --git a/static/img/2022-12-17.firefox.xml-parsing-error.png b/static/img/2022-12-17.firefox.xml-parsing-error.png index 62c9b71..962689d 100644 Binary files a/static/img/2022-12-17.firefox.xml-parsing-error.png and b/static/img/2022-12-17.firefox.xml-parsing-error.png differ diff --git a/static/img/2023-04-25.tailscale.png b/static/img/2023-04-25.tailscale.png index f4aba4e..749580b 100644 Binary files a/static/img/2023-04-25.tailscale.png and b/static/img/2023-04-25.tailscale.png differ diff --git a/static/img/2023-08-10.chartjs.png b/static/img/2023-08-10.chartjs.png index 9bd5146..9522e1a 100644 Binary files a/static/img/2023-08-10.chartjs.png and b/static/img/2023-08-10.chartjs.png differ diff --git a/static/img/ace-jump-mode.png b/static/img/ace-jump-mode.png index fc52672..cf0a74b 100644 Binary files a/static/img/ace-jump-mode.png and b/static/img/ace-jump-mode.png differ diff --git a/static/img/app-search-bar.png b/static/img/app-search-bar.png index 57d9d6f..b9bfe87 100644 Binary files a/static/img/app-search-bar.png and b/static/img/app-search-bar.png differ diff --git a/static/img/browser-caching-after.png b/static/img/browser-caching-after.png index 6145092..9671d6d 100644 Binary files a/static/img/browser-caching-after.png and b/static/img/browser-caching-after.png differ diff --git a/static/img/browser-caching-before.png b/static/img/browser-caching-before.png index 4e51cd3..97e8cc1 100644 Binary files a/static/img/browser-caching-before.png and b/static/img/browser-caching-before.png differ diff --git a/static/img/bulgur-cloud-2022-12-30.png b/static/img/bulgur-cloud-2022-12-30.png index 0daf9cf..60bbd62 100644 Binary files a/static/img/bulgur-cloud-2022-12-30.png and b/static/img/bulgur-cloud-2022-12-30.png differ diff --git a/static/img/bulgur-cloud-basic-html.png b/static/img/bulgur-cloud-basic-html.png index 35daa6e..3856505 100644 Binary files a/static/img/bulgur-cloud-basic-html.png and b/static/img/bulgur-cloud-basic-html.png differ diff --git a/static/img/cc-by-sa-4.0-88x31.png b/static/img/cc-by-sa-4.0-88x31.png index 9bcbea0..5d64b4a 100644 Binary files a/static/img/cc-by-sa-4.0-88x31.png and b/static/img/cc-by-sa-4.0-88x31.png differ diff --git a/static/img/codespaces-devpod-codesandbox-pr.avif b/static/img/codespaces-devpod-codesandbox-pr.avif new file mode 100644 index 0000000..298d5f4 Binary files /dev/null and b/static/img/codespaces-devpod-codesandbox-pr.avif differ diff --git a/static/img/codespaces-devpod-codesandbox.avif b/static/img/codespaces-devpod-codesandbox.avif new file mode 100644 index 0000000..c7baf74 Binary files /dev/null and b/static/img/codespaces-devpod-codesandbox.avif differ diff --git a/static/img/company-flycheck.png b/static/img/company-flycheck.png index 72530c1..ae15c68 100644 Binary files a/static/img/company-flycheck.png and b/static/img/company-flycheck.png differ diff --git a/static/img/deus-ex-render-settings.png b/static/img/deus-ex-render-settings.png index 57b1acc..8b9681d 100644 Binary files a/static/img/deus-ex-render-settings.png and b/static/img/deus-ex-render-settings.png differ diff --git a/static/img/deus-ex-renderer-comparison.png b/static/img/deus-ex-renderer-comparison.png index 01858cb..aeff722 100644 Binary files a/static/img/deus-ex-renderer-comparison.png and b/static/img/deus-ex-renderer-comparison.png differ diff --git a/static/img/devcontainer-debian-example.png b/static/img/devcontainer-debian-example.png index 382f50b..a694f27 100644 Binary files a/static/img/devcontainer-debian-example.png and b/static/img/devcontainer-debian-example.png differ diff --git a/static/img/docview.png b/static/img/docview.png index 618ac8f..5a9cc45 100644 Binary files a/static/img/docview.png and b/static/img/docview.png differ diff --git a/static/img/elfeed.png b/static/img/elfeed.png index 7e89947..d10e80c 100644 Binary files a/static/img/elfeed.png and b/static/img/elfeed.png differ diff --git a/static/img/emacs-terminal.png b/static/img/emacs-terminal.png index 0a84153..908f937 100644 Binary files a/static/img/emacs-terminal.png and b/static/img/emacs-terminal.png differ diff --git a/static/img/erc.png b/static/img/erc.png index d64487f..3fe02a5 100644 Binary files a/static/img/erc.png and b/static/img/erc.png differ diff --git a/static/img/eshell.png b/static/img/eshell.png index c5e2b64..f19df1d 100644 Binary files a/static/img/eshell.png and b/static/img/eshell.png differ diff --git a/static/img/eww.png b/static/img/eww.png index 50da7a4..58efe3d 100644 Binary files a/static/img/eww.png and b/static/img/eww.png differ diff --git a/static/img/game-cover.jpg b/static/img/game-cover.jpg index 39c78dc..bce97a0 100644 Binary files a/static/img/game-cover.jpg and b/static/img/game-cover.jpg differ diff --git a/static/img/gh-do-not-merge-action.png b/static/img/gh-do-not-merge-action.png index c0edf8a..f786de6 100644 Binary files a/static/img/gh-do-not-merge-action.png and b/static/img/gh-do-not-merge-action.png differ diff --git a/static/img/gh-do-not-merge-fail.png b/static/img/gh-do-not-merge-fail.png index 77195e9..b459f9e 100644 Binary files a/static/img/gh-do-not-merge-fail.png and b/static/img/gh-do-not-merge-fail.png differ diff --git a/static/img/gh-menu-actions-general.png b/static/img/gh-menu-actions-general.png index c9a7a84..6bcfbe2 100644 Binary files a/static/img/gh-menu-actions-general.png and b/static/img/gh-menu-actions-general.png differ diff --git a/static/img/gh-repository-defaults-labels.png b/static/img/gh-repository-defaults-labels.png index b46e031..c34c2e3 100644 Binary files a/static/img/gh-repository-defaults-labels.png and b/static/img/gh-repository-defaults-labels.png differ diff --git a/static/img/gh-repository-defaults.png b/static/img/gh-repository-defaults.png index 2591f71..52834a2 100644 Binary files a/static/img/gh-repository-defaults.png and b/static/img/gh-repository-defaults.png differ diff --git a/static/img/gh-required-workflows-config.png b/static/img/gh-required-workflows-config.png index 9103f32..71b6061 100644 Binary files a/static/img/gh-required-workflows-config.png and b/static/img/gh-required-workflows-config.png differ diff --git a/static/img/gh-required-workflows.png b/static/img/gh-required-workflows.png index 073ba90..19bb3bf 100644 Binary files a/static/img/gh-required-workflows.png and b/static/img/gh-required-workflows.png differ diff --git a/static/img/magit.png b/static/img/magit.png index 16e87cc..8aaf01c 100644 Binary files a/static/img/magit.png and b/static/img/magit.png differ diff --git a/static/img/mu4e.png b/static/img/mu4e.png index d02eb7e..04bff37 100644 Binary files a/static/img/mu4e.png and b/static/img/mu4e.png differ diff --git a/static/img/passmenu.png b/static/img/passmenu.png index c1cefbd..514ae47 100644 Binary files a/static/img/passmenu.png and b/static/img/passmenu.png differ diff --git a/static/img/password_store.png b/static/img/password_store.png index 787db15..b4c3e0a 100644 Binary files a/static/img/password_store.png and b/static/img/password_store.png differ diff --git a/static/img/profile.2022.12.avif b/static/img/profile.2022.12.avif index a204b0e..5030a6c 100644 Binary files a/static/img/profile.2022.12.avif and b/static/img/profile.2022.12.avif differ diff --git a/static/img/profile.2022.12.jpeg b/static/img/profile.2022.12.jpeg index 03d1486..b83a1d8 100644 Binary files a/static/img/profile.2022.12.jpeg and b/static/img/profile.2022.12.jpeg differ diff --git a/static/img/profile.2022.12.webp b/static/img/profile.2022.12.webp index c413e85..86af945 100644 Binary files a/static/img/profile.2022.12.webp and b/static/img/profile.2022.12.webp differ diff --git a/static/img/profile.jpg b/static/img/profile.jpg index 6f78586..10d26a5 100644 Binary files a/static/img/profile.jpg and b/static/img/profile.jpg differ diff --git a/static/img/react-redux-after-flamegraph.png b/static/img/react-redux-after-flamegraph.png index 3b78162..208b850 100644 Binary files a/static/img/react-redux-after-flamegraph.png and b/static/img/react-redux-after-flamegraph.png differ diff --git a/static/img/react-redux-component-hooks.png b/static/img/react-redux-component-hooks.png index 78e67a9..72eb27f 100644 Binary files a/static/img/react-redux-component-hooks.png and b/static/img/react-redux-component-hooks.png differ diff --git a/static/img/react-redux-rerender-flamegraph.png b/static/img/react-redux-rerender-flamegraph.png index 3748258..828d845 100644 Binary files a/static/img/react-redux-rerender-flamegraph.png and b/static/img/react-redux-rerender-flamegraph.png differ diff --git a/static/img/tor-censorship-snowflake-chart.webp b/static/img/tor-censorship-snowflake-chart.webp index 8a77b46..9cf3c16 100644 Binary files a/static/img/tor-censorship-snowflake-chart.webp and b/static/img/tor-censorship-snowflake-chart.webp differ diff --git a/static/vid/react-redux-causes-re-renders.mp4 b/static/vid/react-redux-causes-re-renders.mp4 index f53b442..fc7d4e7 100644 Binary files a/static/vid/react-redux-causes-re-renders.mp4 and b/static/vid/react-redux-causes-re-renders.mp4 differ