Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: "Release"

on:
push:
branches:
- main

jobs:
deploy:
name: "Release to GHCR"
if: ${{ github.ref == 'refs/heads/main' }}
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
packages: write
steps:
- uses: actions/checkout@v6

- name: "Publish features"
uses: devcontainers/action@v1
with:
publish-features: "true"
base-path-to-features: "./src"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
65 changes: 65 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: "Test"

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

jobs:
docs:
name: "Ensure documentation has been generated"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: "Install devcontainer CLI"
run: npm install -g @devcontainers/cli

- name: "Generate docs"
run: devcontainer features generate-docs -p src -n csutter/devcontainer-features

- name: "Verify docs are up to date"
run: git diff --quiet -- */**/README.md

shellcheck:
name: Shellcheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Run ShellCheck
uses: ludeeus/action-shellcheck@2.0.0

test:
name: "Test ${{ matrix.feature }} on ${{ matrix.baseImage }}"
runs-on: ubuntu-latest
continue-on-error: true
strategy:
matrix:
feature:
- personal-setup
baseImage:
# Vanilla distribution images
- docker.io/library/debian:latest
- docker.io/library/ubuntu:latest
- quay.io/fedora/fedora-toolbox:latest
# Microsoft devcontainer base image
- mcr.microsoft.com/devcontainers/base:ubuntu
steps:
- uses: actions/checkout@v4

# The personal-setup feature requires my dotfiles folders to be present in the expected
# location, so clone the public repo to simulate this, and fake the private repo mount.
- name: "Prepare demo dotfiles mounts"
run: |
mkdir -p $HOME/src/csutter
mkdir $HOME/src/csutter/dotfiles-private
git clone https://github.com/csutter/dotfiles.git $HOME/src/csutter/dotfiles

- name: "Install devcontainer CLI"
run: npm install -g @devcontainers/cli

- name: "Test feature: ${{ matrix.feature }} on ${{ matrix.baseImage }}"
run: devcontainer features test --features ${{ matrix.feature }} --base-image ${{ matrix.baseImage }}
2 changes: 2 additions & 0 deletions .shellcheckrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Don't follow external sources
disable=SC1091
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
# devcontainer-features
Feature definitions for my containerised development environments

> [!CAUTION]
> This repository contains assorted devcontainer features meant to be used by _me_ personally:
> * as default features for all (own and third party) devcontainers I run, or
> * as features in specific devcontainers for my own personal projects
>
> You may or may not get much mileage out of using them directly, and any or all features may not be
> stable, continue to provide the same functionality in the long run, always be available on
> `ghcr.io`, or even work on anyone else's machine!
>
> I therefore recommend that you use this repository as inspiration for your own features, and do
> not rely on them directly.

## Features
* [`personal-setup`](src/personal-setup/): Sets up tooling and dotfiles for any arbitrary devcontainer
23 changes: 23 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[tools]
node = "24"
"npm:@devcontainers/cli" = "0.80"
"github:koalaman/shellcheck" = "v0.11.0"

[tasks.docs]
description = "Generate documentation for all features"
# Note: The `generate-docs` command documentation wrongly suggests -p should be the root of the
# repo, but it should be the src/ directory.
run = "devcontainer features generate-docs -p src -n csutter/devcontainer-features"

[tasks.lint-shell]
description = "Lint all shell scripts using ShellCheck"
run = "find . -name '*.sh' -print0 | xargs -0 shellcheck"

[tasks.test]
description = "Run tests for all features"
run = [
"devcontainer features test -i docker.io/library/debian:latest",
"devcontainer features test -i docker.io/library/ubuntu:latest",
"devcontainer features test -i quay.io/fedora/fedora-toolbox:latest",
"devcontainer features test -i mcr.microsoft.com/devcontainers/base:ubuntu",
]
19 changes: 19 additions & 0 deletions src/personal-setup/NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
I have a set of preferred tools that I want available in any devcontainer, as well as several
dotfiles repositories to configure my desired development environment.

I've previously (ab)used the _Dev Containers_ extension's built in dotfiles support, but it:
- doesn't allow multiple dotfiles repositories (a key use case for me)
- relies on an install script in the repository (which feels like an unsuitable concern for a
repository of configuration files)
- clones the repository from origin every time (which requires SSH agent confirmation and needs
"human in the loop" during setup, and means changes on the host don't get picked up until push and
a full container rebuild)

This feature:
- Installs a set of packages in the container (including `rcm` for dotfiles management)
- Mounts my dotfiles repositories into the container
- Installs the dotfiles (with appropriate tags)

This feature is intended to be configured as part of my personal user settings as a default feature
for all devcontainers (through `dev.containers.defaultFeatures`). It's obviously specific to me,
and coupled to my canonical directory layout and dotfiles repositories.
39 changes: 39 additions & 0 deletions src/personal-setup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

# Personal Setup (personal-setup)

Sets up my desired software and configuration for any devcontainer environment.

## Example Usage

```json
"features": {
"ghcr.io/csutter/devcontainer-features/personal-setup:1": {}
}
```



I have a set of preferred tools that I want available in any devcontainer, as well as several
dotfiles repositories to configure my desired development environment.

I've previously (ab)used the _Dev Containers_ extension's built in dotfiles support, but it:
- doesn't allow multiple dotfiles repositories (a key use case for me)
- relies on an install script in the repository (which feels like an unsuitable concern for a
repository of configuration files)
- clones the repository from origin every time (which requires SSH agent confirmation and needs
"human in the loop" during setup, and means changes on the host don't get picked up until push and
a full container rebuild)

This feature:
- Installs a set of packages in the container (including `rcm` for dotfiles management)
- Mounts my dotfiles repositories into the container
- Installs the dotfiles (with appropriate tags)

This feature is intended to be configured as part of my personal user settings as a default feature
for all devcontainers (through `dev.containers.defaultFeatures`). It's obviously specific to me,
and coupled to my canonical directory layout and dotfiles repositories.


---

_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._
22 changes: 22 additions & 0 deletions src/personal-setup/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id": "personal-setup",
"version": "1.0.0",
"name": "Personal Setup",
"description": "Sets up my desired software and configuration for any devcontainer environment.",
"mounts": [
{
"type": "bind",
"source": "${localEnv:HOME}/src/csutter/dotfiles",
"target": "/mnt/dotfiles"
},
{
"type": "bind",
"source": "${localEnv:HOME}/src/csutter/dotfiles-private",
"target": "/mnt/dotfiles-private"
}
],
"containerEnv": {
"RCRC": "/mnt/dotfiles/tag-devcontainer/rcrc"
},
"postCreateCommand": "rcup -vf"
}
25 changes: 25 additions & 0 deletions src/personal-setup/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/bash
set -e

if [ -f /etc/os-release ]; then
. /etc/os-release
else
echo "Error: Cannot detect distribution (no /etc/os-release)"
exit 1
fi

echo "Installing packages for distribution: $ID"
case "$ID" in
debian|ubuntu)
apt-get update
apt-get install -y rcm
;;
fedora)
dnf install -y rcm
;;
*)
echo "Error: Unsupported distribution: $ID"
echo "This feature supports: debian, ubuntu, fedora"
exit 1
;;
esac
10 changes: 10 additions & 0 deletions test/personal-setup/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash
set -e

source dev-container-features-test-lib

check "rcm is available" bash -c "which rcup"
# Use a dotfile that should _always_ be present on any system
check "dotfiles are installed" bash -c "test -f $HOME/.config/fish/config.fish"

reportResults