diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..694475f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,26 @@ +{ + "image": "mcr.microsoft.com/devcontainers/javascript-node:1-20-bookworm", + "customizations": { + "vscode": { + "settings": { + "json.schemas": [ + { + "fileMatch": [ + "*/devcontainer-feature.json" + ], + "url": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainerFeature.schema.json" + } + ] + }, + "extensions": [ + "mads-hartmann.bash-ide-vscode", + "github.vscode-github-actions" + ] + } + }, + "features": { + "ghcr.io/devcontainers/features/docker-in-docker:2": {} + }, + "remoteUser": "node", + "updateContentCommand": "npm install -g @devcontainers/cli" +} \ No newline at end of file diff --git a/.github/workflows/features-release.yml b/.github/workflows/features-release.yml new file mode 100644 index 0000000..5e7377f --- /dev/null +++ b/.github/workflows/features-release.yml @@ -0,0 +1,47 @@ +name: "Release dev container features & Generate Documentation" +on: + workflow_dispatch: + +jobs: + deploy: + if: ${{ github.ref == 'refs/heads/master' }} + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + packages: write + steps: + - uses: actions/checkout@v4 + + - name: "Publish Features" + uses: devcontainers/action@v1 + with: + publish-features: "true" + base-path-to-features: "./src" + generate-docs: "true" + + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Create PR for Documentation + id: push_image_info + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -e + echo "Start." + # Configure git and Push updates + git config --global user.email github-actions[bot]@users.noreply.github.com + git config --global user.name github-actions[bot] + git config pull.rebase false + branch=automated-documentation-update-$GITHUB_RUN_ID + git checkout -b $branch + message='Automated documentation update' + # Add / update and commit + git add */**/README.md + git commit -m 'Automated documentation update [skip ci]' || export NO_UPDATES=true + # Push + if [ "$NO_UPDATES" != "true" ] ; then + git push origin "$branch" + gh pr create --title "$message" --body "$message" + fi \ No newline at end of file diff --git a/.github/workflows/features-test.yml b/.github/workflows/features-test.yml new file mode 100644 index 0000000..4acc787 --- /dev/null +++ b/.github/workflows/features-test.yml @@ -0,0 +1,64 @@ +name: "CI - Test Features" +on: + push: + branches: + - master + pull_request: + workflow_dispatch: + +jobs: + test-autogenerated: + runs-on: ubuntu-latest + continue-on-error: true + strategy: + matrix: + features: + - 7z + - bannerlord + - mono + - upgrade + - vortex + baseImage: + - debian:latest + - ubuntu:latest + - mcr.microsoft.com/devcontainers/base:ubuntu + steps: + - uses: actions/checkout@v4 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'" + run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }} . + + test-scenarios: + runs-on: ubuntu-latest + continue-on-error: true + strategy: + matrix: + features: + - 7z + - bannerlord + - mono + - upgrade + - vortex + steps: + - uses: actions/checkout@v4 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Generating tests for '${{ matrix.features }}' scenarios" + run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated --skip-duplicated . + + test-global: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v4 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Testing global scenarios" + run: devcontainer features test --global-scenarios-only . \ No newline at end of file diff --git a/.github/workflows/features-validate.yml b/.github/workflows/features-validate.yml new file mode 100644 index 0000000..f4483f4 --- /dev/null +++ b/.github/workflows/features-validate.yml @@ -0,0 +1,16 @@ +name: "Validate devcontainer-feature.json files" +on: + workflow_dispatch: + pull_request: + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: "Validate devcontainer-feature.json files" + uses: devcontainers/action@v1 + with: + validate-only: "true" + base-path-to-features: "./features" \ No newline at end of file diff --git a/.github/workflows/image-release.yml b/.github/workflows/image-release.yml new file mode 100644 index 0000000..0393461 --- /dev/null +++ b/.github/workflows/image-release.yml @@ -0,0 +1,58 @@ +name: Dev Container Build and Push Image + +on: + push: + branches: + - master + paths: + - '.image-base/**/*' + workflow_dispatch: + +jobs: + build-and-publish-docker: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: all + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Login to Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: BUTR + password: ${{ secrets.TOKEN_GPR }} + + - name: Build and Push + id: docker_build + uses: docker/build-push-action@v5 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ./ + file: ./image-base/Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: ghcr.io/butr/devcontainer:latest + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache + + - name: Image digest + run: echo ${{ steps.docker_build.outputs.digest }} \ No newline at end of file diff --git a/features/7z/devcontainer-feature.json b/features/7z/devcontainer-feature.json new file mode 100644 index 0000000..f2b8ad8 --- /dev/null +++ b/features/7z/devcontainer-feature.json @@ -0,0 +1,7 @@ +{ + "id": "7z", + "version": "1.0.0", + "name": "7z", + "documentationURL": "", + "description": "7z" +} \ No newline at end of file diff --git a/features/7z/install.sh b/features/7z/install.sh new file mode 100644 index 0000000..26a7c61 --- /dev/null +++ b/features/7z/install.sh @@ -0,0 +1,10 @@ +#!/bin/bash +export DEBIAN_FRONTEND=noninteractive + +echo "(*) Installing 7z" +apt-get update +apt-get install -y --no-install-recommends p7zip-full +apt-get clean -y +rm -rf /var/lib/apt/lists/*; + +echo "Done!" \ No newline at end of file diff --git a/features/bannerlord/devcontainer-feature.json b/features/bannerlord/devcontainer-feature.json new file mode 100644 index 0000000..9bbee90 --- /dev/null +++ b/features/bannerlord/devcontainer-feature.json @@ -0,0 +1,17 @@ +{ + "id": "bannerlord", + "version": "1.0.0", + "name": "Bannerlord", + "documentationURL": "", + "description": "Bannerlord", + "containerEnv": { + "BANNERLORD_GAME_DIR": "/bannerlord" + }, + "mounts": [ + { + "source":"${localEnv:BANNERLORD_GAME_DIR}", + "target":"/bannerlord", + "type":"bind" + } + ] +} \ No newline at end of file diff --git a/features/bannerlord/install.sh b/features/bannerlord/install.sh new file mode 100644 index 0000000..a4fb79f --- /dev/null +++ b/features/bannerlord/install.sh @@ -0,0 +1,2 @@ +#!/bin/bash +export DEBIAN_FRONTEND=noninteractive \ No newline at end of file diff --git a/features/mono/devcontainer-feature.json b/features/mono/devcontainer-feature.json new file mode 100644 index 0000000..c37d398 --- /dev/null +++ b/features/mono/devcontainer-feature.json @@ -0,0 +1,7 @@ +{ + "id": "mono", + "version": "1.0.0", + "name": "Mono", + "documentationURL": "", + "description": "Mono" +} \ No newline at end of file diff --git a/features/mono/install.sh b/features/mono/install.sh new file mode 100644 index 0000000..113ba42 --- /dev/null +++ b/features/mono/install.sh @@ -0,0 +1,10 @@ +#!/bin/bash +export DEBIAN_FRONTEND=noninteractive + +echo "(*) Installing mono" +apt-get update +apt-get install -y --no-install-recommends mono-devel +apt-get clean -y +rm -rf /var/lib/apt/lists/*; + +echo "Done!" \ No newline at end of file diff --git a/features/upgrade/devcontainer-feature.json b/features/upgrade/devcontainer-feature.json new file mode 100644 index 0000000..722ab1f --- /dev/null +++ b/features/upgrade/devcontainer-feature.json @@ -0,0 +1,7 @@ +{ + "id": "upgrade", + "version": "1.0.0", + "name": "Upgrade", + "documentationURL": "", + "description": "Upgrade" +} \ No newline at end of file diff --git a/features/upgrade/install.sh b/features/upgrade/install.sh new file mode 100644 index 0000000..fabb56b --- /dev/null +++ b/features/upgrade/install.sh @@ -0,0 +1,10 @@ +#!/bin/bash +export DEBIAN_FRONTEND=noninteractive + +echo "(*) Upgrading" +apt-get update +apt-get upgrade -y +apt-get clean -y +rm -rf /var/lib/apt/lists/*; + +echo "Done!" \ No newline at end of file diff --git a/features/vortex/devcontainer-feature.json b/features/vortex/devcontainer-feature.json new file mode 100644 index 0000000..9f52d2d --- /dev/null +++ b/features/vortex/devcontainer-feature.json @@ -0,0 +1,14 @@ +{ + "id": "vortex", + "version": "1.0.0", + "name": "Vortex", + "documentationURL": "", + "description": "Vortex", + "mounts": [ + { + "source":"${localEnv:HOME}${localEnv:USERPROFILE}/AppData/Roaming/Vortex/plugins", + "target":"/vortex-plugins", + "type":"bind" + } + ] + } \ No newline at end of file diff --git a/features/vortex/install.sh b/features/vortex/install.sh new file mode 100644 index 0000000..a4fb79f --- /dev/null +++ b/features/vortex/install.sh @@ -0,0 +1,2 @@ +#!/bin/bash +export DEBIAN_FRONTEND=noninteractive \ No newline at end of file diff --git a/image-base/Dockerfile b/image-base/Dockerfile new file mode 100644 index 0000000..81ca0f0 --- /dev/null +++ b/image-base/Dockerfile @@ -0,0 +1,21 @@ +# [Choice] Debian version (use bullseye on local arm64/Apple Silicon): bookworm, bullseye, buster +ARG VARIANT="bookworm" +FROM buildpack-deps:${VARIANT}-curl + +USER root + +ARG USERNAME=developer +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +# Create the user +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME \ + # + # [Optional] Add sudo support. Omit if you don't need to install software after connecting. + && apt-get update \ + && apt-get install -y sudo \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +USER $USERNAME