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
40 changes: 40 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Test Docker image

on:
pull_request:
branches:
- latest
push:
branches:
- latest
workflow_dispatch:

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
platform: [linux/amd64, linux/arm64]
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Install container-structure-test
run: |
if [ "${{ matrix.platform }}" == "linux/arm64" ]; then
ARCH="arm64"
else
ARCH="amd64"
fi
curl -LO "https://storage.googleapis.com/container-structure-test/latest/container-structure-test-linux-${ARCH}"
chmod +x "container-structure-test-linux-${ARCH}"
sudo mv "container-structure-test-linux-${ARCH}" /usr/local/bin/container-structure-test

- name: Run tests
run: ./test.sh "${{ matrix.platform }}"
26 changes: 25 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# syntax=docker/dockerfile:1
FROM ubuntu:24.04 AS base
FROM ubuntu:25.10 AS base

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Using Ubuntu 25.10, which is an interim release, for a base image is not recommended. Interim releases have a short 9-month support cycle and are less stable than Long-Term Support (LTS) releases. For a development image that should be stable and reliable, it's much safer to stick with an LTS version like ubuntu:24.04 (the latest LTS) or ubuntu:22.04. This ensures you get security updates and stability for a much longer period (5 years).

FROM ubuntu:24.04 AS base


ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
Expand Down Expand Up @@ -29,6 +29,30 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
jq \
zsh \
postgresql-client \
# Better alternative to grep
ripgrep \
# Better alternative to find
fd-find \
# Better alternative to top/htop
btop \
# Better alternative to ls
eza \
# Better alternative to du
du-dust \
# Better alternative to cat
bat \
# Pager for bat
less \
# Fuzzy finder
fzf \
# Code counter
tokei \
# Benchmarking tool
hyperfine \
# Linking preferred alternatives
&& ln -s /usr/bin/eza /usr/local/bin/ls \
&& ln -s /usr/bin/batcat /usr/local/bin/bat \
Comment on lines +53 to +54
Copy link

Copilot AI Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overriding the system ls command with a symlink to eza can cause compatibility issues with scripts or tools that depend on the standard ls behavior and flags. While eza is largely compatible with ls, there may be subtle differences in output format or flag handling that could break existing automation. Consider creating an alias instead (e.g., in a shell configuration file) or documenting this breaking change prominently, especially since this is a base image that other projects will use.

Suggested change
&& ln -s /usr/bin/eza /usr/local/bin/ls \
&& ln -s /usr/bin/batcat /usr/local/bin/bat \
# Do NOT override ls with eza to avoid breaking scripts
&& ln -s /usr/bin/batcat /usr/local/bin/bat \
# Add alias for interactive shells
&& echo "alias ls='eza'" >> /etc/bash.bashrc \
&& echo "alias ls='eza'" >> /etc/zsh/zshrc \

Copilot uses AI. Check for mistakes.
&& ln -s /usr/bin/fdfind /usr/local/bin/fd \
# Install uv:
&& curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="/usr/local/bin" sh \
# Install Pulumi:
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ It contains the necessary dependencies for running various linters and type chec
- `hadolint` - for linting Dockerfile
- `actionlint` - static checker for GitHub Actions workflow files

Alternative unix power tools:

- `rg` (ripgrep) - better alternative to `grep`
- `fd` - better alternative to `find`
- `btop` - better alternative to `top`/`htop`
- `eza` - better alternative to `ls` *(symlinked to replace `ls`)*
- `dust` - better alternative to `du`
- `bat` - better alternative to `cat`
- `fzf` - fuzzy finder
- `tokei` - code counter
- `hyperfine` - benchmarking tool

Other tools:

- `pulumi` - Pulumi CLI for infrastructure as code
Expand Down
20 changes: 17 additions & 3 deletions test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ TEST_IMAGE="python-dev-test-image"

platforms="${1:-linux/amd64 linux/arm64}"

# Check if container-structure-test supports --platform flag
# Linux binaries of container-structure-test may not support --platform flag
# and thus can only run tests for the local architecture.
PLATFORM_FLAG=""
if container-structure-test test --help 2>&1 | grep -q -- '--platform'; then
PLATFORM_FLAG="--platform"
fi

# Build and test function that takes platform as parameter
build_and_test() {
local platform=$1
Expand All @@ -32,14 +40,20 @@ build_and_test() {

docker run --platform "$platform" --rm "$TEST_PLATFORM_IMAGE" uname -m

# Conditionally add --platform flag
PLATFORM_ARG=""
if [ -n "$PLATFORM_FLAG" ]; then
PLATFORM_ARG="--platform $platform"
fi

if [ "$platform" == "linux/amd64" ]; then
container-structure-test test --platform "$platform" --image "$TEST_PLATFORM_IMAGE" --config tests/amd64.yaml
container-structure-test test "$PLATFORM_ARG" --image "$TEST_PLATFORM_IMAGE" --config tests/amd64.yaml
else
container-structure-test test --platform "$platform" --image "$TEST_PLATFORM_IMAGE" --config tests/arm64.yaml
container-structure-test test "$PLATFORM_ARG" --image "$TEST_PLATFORM_IMAGE" --config tests/arm64.yaml
fi

# Run the tests
container-structure-test test --platform "$platform" --image "$TEST_PLATFORM_IMAGE" --config tests/specs.yaml
container-structure-test test "$PLATFORM_ARG" --image "$TEST_PLATFORM_IMAGE" --config tests/specs.yaml

# Clean up
docker rmi $TEST_IMAGE:"$tag" || true
Expand Down
41 changes: 41 additions & 0 deletions tests/specs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,44 @@ commandTests:
- name: "psql is installed in path"
command: "psql"
args: ["--version"]

- name: "ripgrep is installed in path"
command: "rg"
args: ["--version"]

- name: "fd is installed in path"
command: "fd"
args: ["--version"]

- name: "btop is installed in path"
command: "btop"
args: ["--version"]

- name: "eza is installed in path"
command: "eza"
args: ["--version"]

- name: "ls is overridden by eza"
command: "ls"
args: ["--version"]
expectedOutput: ["eza"]

- name: "dust is installed in path"
command: "dust"
args: ["--version"]

- name: "bat is installed in path"
command: "bat"
args: ["--version"]

- name: "fzf is installed in path"
command: "fzf"
args: ["--version"]

- name: "tokei is installed in path"
command: "tokei"
args: ["--version"]

- name: "hyperfine is installed in path"
command: "hyperfine"
args: ["--version"]