diff --git a/.github/actions/smoke-test/action.yaml b/.github/actions/smoke-test/action.yaml new file mode 100644 index 00000000..29ed4475 --- /dev/null +++ b/.github/actions/smoke-test/action.yaml @@ -0,0 +1,23 @@ +name: "Smoke test" +description: "Tests the provided template." +inputs: + template: + description: "Template to test" + required: true + +runs: + using: composite + steps: + - name: Checkout main + id: checkout_release + uses: actions/checkout@v3 + + - name: Build template + id: build_template + shell: bash + run: ${{ github.action_path }}/build.sh ${{ inputs.template }} + + - name: Test template + id: test_template + shell: bash + run: ${{ github.action_path }}/test.sh ${{ inputs.template }} diff --git a/.github/actions/smoke-test/build.sh b/.github/actions/smoke-test/build.sh new file mode 100755 index 00000000..5f7cf419 --- /dev/null +++ b/.github/actions/smoke-test/build.sh @@ -0,0 +1,55 @@ +#!/bin/bash +TEMPLATE_ID="$1" + +set -e + +shopt -s dotglob + +SRC_DIR="/tmp/${TEMPLATE_ID}" +cp -R "templates/src/${TEMPLATE_ID}" "${SRC_DIR}" + +pushd "${SRC_DIR}" + +# Configure templates only if `devcontainer-template.json` contains the `options` property. +OPTION_PROPERTY=( $(jq -r '.options' devcontainer-template.json) ) + +if [ "${OPTION_PROPERTY}" != "" ] && [ "${OPTION_PROPERTY}" != "null" ] ; then + OPTIONS=( $(jq -r '.options | keys[]' devcontainer-template.json) ) + + if [ "${OPTIONS[0]}" != "" ] && [ "${OPTIONS[0]}" != "null" ] ; then + echo "(!) Configuring template options for '${TEMPLATE_ID}'" + for OPTION in "${OPTIONS[@]}" + do + OPTION_KEY="\${templateOption:$OPTION}" + OPTION_VALUE=$(jq -r ".options | .${OPTION} | .default" devcontainer-template.json) + + if [ "${OPTION_VALUE}" = "" ] || [ "${OPTION_VALUE}" = "null" ] ; then + echo "Template '${TEMPLATE_ID}' is missing a default value for option '${OPTION}'" + exit 1 + fi + + echo "(!) Replacing '${OPTION_KEY}' with '${OPTION_VALUE}'" + OPTION_VALUE_ESCAPED=$(sed -e 's/[]\/$*.^[]/\\&/g' <<<"${OPTION_VALUE}") + find ./ -type f -print0 | xargs -0 sed -i "s/${OPTION_KEY}/${OPTION_VALUE_ESCAPED}/g" + done + fi +fi + +popd + +TEST_DIR="test/${TEMPLATE_ID}" +if [ -d "${TEST_DIR}" ] ; then + echo "(*) Copying test folder" + DEST_DIR="${SRC_DIR}/test-project" + mkdir -p ${DEST_DIR} + cp -Rp ${TEST_DIR}/* ${DEST_DIR} + cp test/test-utils/test-utils.sh ${DEST_DIR} +fi + +export DOCKER_BUILDKIT=1 +echo "(*) Installing @devcontainer/cli" +npm install -g @devcontainers/cli + +echo "Building Dev Container" +ID_LABEL="test-container=${TEMPLATE_ID}" +devcontainer up --id-label ${ID_LABEL} --workspace-folder "${SRC_DIR}" diff --git a/.github/actions/smoke-test/test.sh b/.github/actions/smoke-test/test.sh new file mode 100755 index 00000000..5de1a2c7 --- /dev/null +++ b/.github/actions/smoke-test/test.sh @@ -0,0 +1,13 @@ +#!/bin/bash +TEMPLATE_ID="$1" +set -e + +SRC_DIR="/tmp/${TEMPLATE_ID}" +echo "Running Smoke Test" + +ID_LABEL="test-container=${TEMPLATE_ID}" +devcontainer exec --workspace-folder "${SRC_DIR}" --id-label ${ID_LABEL} /bin/sh -c 'set -e && if [ -f "test-project/test.sh" ]; then cd test-project && if [ "$(id -u)" = "0" ]; then chmod +x test.sh; else sudo chmod +x test.sh; fi && ./test.sh; else ls -a; fi' + +# Clean up +docker rm -f $(docker container ls -f "label=${ID_LABEL}" -q) +rm -rf "${SRC_DIR}" diff --git a/.github/workflows/baseimage-builder.yaml b/.github/workflows/baseimage-builder.yaml deleted file mode 100644 index 8acb596d..00000000 --- a/.github/workflows/baseimage-builder.yaml +++ /dev/null @@ -1,65 +0,0 @@ -name: "Build Dockerfile for Mamba-based Environment" - -on: - workflow_call: - inputs: - docker_tag: - required: true - type: string - build_context: - required: true - type: string - -jobs: - build-environment: - runs-on: "ubuntu-latest" - steps: - - id: "setup" - run: | - echo "build-date=$(date)" >> $GITHUB_OUTPUT - - - id: "checkout" - name: "Checkout repository" - uses: "actions/checkout@v3" - - - id: "setup-qemu" - name: "Setup QEMU" - uses: "docker/setup-qemu-action@v2" - with: - platforms: "linux/amd64,linux/arm64" - - - id: "setup-buildx" - name: "Setup Buildx" - uses: "docker/setup-buildx-action@v2" - with: - install: true - - - id: "login-dockerhub" - name: "Login to DockerHub" - uses: "docker/login-action@v2" - with: - username: "${{ secrets.DOCKERHUB_USERNAME }}" - password: "${{ secrets.DOCKERHUB_TOKEN }}" - - - id: "login-ghcr" - name: "Login to GitHub Container Registry" - uses: "docker/login-action@v2" - with: - registry: "ghcr.io" - username: "${{ github.repository_owner }}" - password: "${{ secrets.GITHUB_TOKEN }}" - - - id: "build" - name: "Build and push Docker images" - uses: "docker/build-push-action@v3" - with: - push: true - platforms: "linux/amd64,linux/arm64" - context: "${{ inputs.build_context }}" - build-args: | - BUILD_DATE=${{ steps.setup.outputs.build-date }} - tags: | - ${{ secrets.DOCKERHUB_USERNAME }}/baseimage:${{ inputs.docker_tag }} - ${{ secrets.DOCKERHUB_USERNAME }}/baseimage:${{ inputs.docker_tag }}-${{ github.sha }} - ghcr.io/${{ github.repository_owner }}/baseimage:${{ inputs.docker_tag }} - ghcr.io/${{ github.repository_owner }}/baseimage:${{ inputs.docker_tag }}-${{ github.sha }} diff --git a/.github/workflows/baseimage-metabuilder.yaml b/.github/workflows/baseimage-metabuilder.yaml deleted file mode 100644 index f8e1ea1d..00000000 --- a/.github/workflows/baseimage-metabuilder.yaml +++ /dev/null @@ -1,61 +0,0 @@ -name: "Build 'metabuilder' image shared across 'baseimage'" - -on: - push: - paths: - - "baseimage/**" - - ".github/workflows/baseimage-metabuilder.yaml" - workflow_call: - workflow_dispatch: - -jobs: - build-environment: - runs-on: "ubuntu-latest" - steps: - - id: "setup" - run: | - echo "build-date=$(date)" >> $GITHUB_OUTPUT - - - id: "checkout" - name: "Checkout repository" - uses: "actions/checkout@v3" - - - id: "setup-qemu" - name: "Setup QEMU" - uses: "docker/setup-qemu-action@v2" - with: - platforms: "linux/amd64,linux/arm64" - - - id: "setup-buildx" - name: "Setup Buildx" - uses: "docker/setup-buildx-action@v2" - with: - install: true - - - id: "login-dockerhub" - name: "Login to DockerHub" - uses: "docker/login-action@v2" - with: - username: "${{ secrets.DOCKERHUB_USERNAME }}" - password: "${{ secrets.DOCKERHUB_TOKEN }}" - - - id: "login-ghcr" - name: "Login to GitHub Container Registry" - uses: "docker/login-action@v2" - with: - registry: "ghcr.io" - username: "${{ github.repository_owner }}" - password: "${{ secrets.GITHUB_TOKEN }}" - - - id: "build" - name: "Build and push Docker images" - uses: "docker/build-push-action@v3" - with: - push: true - platforms: "linux/amd64,linux/arm64" - context: "baseimage" - build-args: | - BUILD_DATE=${{ steps.setup.outputs.build-date }} - tags: | - ${{ secrets.DOCKERHUB_USERNAME }}/baseimage:metabuilder-latest - ghcr.io/${{ github.repository_owner }}/baseimage:metabuilder-latest diff --git a/.github/workflows/baseimage.yaml b/.github/workflows/baseimage.yaml deleted file mode 100644 index 85057e83..00000000 --- a/.github/workflows/baseimage.yaml +++ /dev/null @@ -1,50 +0,0 @@ -name: "Build all `baseimage` Containers" - -on: - push: - paths: - - "docker.d/**/Dockerfile" - - "versions.d/*.json" - workflow_dispatch: - workflow_run: - workflows: ["Check versions of relevant programming languages"] - types: [completed] - -jobs: - generate-matrix: - name: "Generate Job Matrix for `baseimage` construction" - runs-on: "ubuntu-latest" - outputs: - matrix: "${{ steps.generate-matrix.outputs.matrix }}" - steps: - - id: "checkout" - uses: "actions/checkout@v3" - with: - fetch-depth: 3 - - - name: Run changed-files with dir_names - id: changed-files - uses: tj-actions/changed-files@v35 - with: - path: "docker.d/" - dir_names: "true" - diff_relative: "true" - json: "true" - - - id: "generate-matrix" - name: "Generate Matrix of Docker Images to Build" - run: | - echo "${{ steps.changed-files.outputs.all_modified_files }}" - echo "matrix=${{ steps.changed-files.outputs.all_modified_files }}" >> "$GITHUB_OUTPUT" - - build-baseimages: - needs: "generate-matrix" - strategy: - matrix: - docker_tag: "${{ fromJson(needs.generate-matrix.outputs.matrix) }}" - name: "${{ matrix.name }}" - uses: "./.github/workflows/baseimage-builder.yaml" - with: - docker_tag: "${{ matrix.docker_tag }}" - build_context: "docker.d/${{ matrix.docker_tag }}" - secrets: inherit diff --git a/.github/workflows/get-versions-builder.yaml b/.github/workflows/get-versions-builder.yaml deleted file mode 100644 index 482a0aeb..00000000 --- a/.github/workflows/get-versions-builder.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: "Get language-specific releases" - -on: - workflow_call: - inputs: - language: - required: true - type: string - -jobs: - check-versions: - runs-on: "ubuntu-latest" - steps: - - id: "checkout" - name: "Checkout `containers` repository" - uses: "actions/checkout@v3" - with: - fetch-depth: 0 - - - id: "checkout-HEAD" - run: | - git pull - git checkout HEAD - - - id: "setup-node" - name: "Setup NodeJS" - uses: "actions/setup-node@v3" - with: - node-version: "18" - - - id: "setup-pnpm" - name: "Setup `pnpm`" - uses: "pnpm/action-setup@v2" - with: - version: "latest" - run_install: false - - - name: "Get `pnpm` store" - id: "pnpm-store" - shell: "bash" - run: | - echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - - - uses: "actions/cache@v3" - id: "pnpm-cache" - name: "Setup `pnpm` cache" - with: - path: "${{ steps.pnpm-store.outputs.STORE_PATH }}" - key: "${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}" - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: "Install dependencies" - id: "pnpm-install" - run: "pnpm install" - - - name: "Checks DockerHub for Language Version Bumps" - run: | - pnpm get-versions -l ${{ inputs.language }} - - - name: "Add `.versions.d/${{ inputs.language }}.json`" - uses: "endbug/add-and-commit@v9" - with: - add: "./versions.d/${{ inputs.language }}.json" - message: "Tracking `.versions.d/${{ inputs.language }}.json` to latest versions" - push: true \ No newline at end of file diff --git a/.github/workflows/get-versions.yaml b/.github/workflows/get-versions.yaml deleted file mode 100644 index 95c61baf..00000000 --- a/.github/workflows/get-versions.yaml +++ /dev/null @@ -1,106 +0,0 @@ -name: "Check versions of relevant programming languages" - -on: - push: - paths: - - ".github/workflows/get-versions.yaml" - - ".github/workflows/get-versions-builder.yaml" - - "versions.d/get-versions.mjs" - - "versions.d/_sources.jsonc" - - "Dockerfile.njk" - schedule: - - cron: "5 4 * * */7" - workflow_dispatch: - -jobs: - check-python: - if: "${{ always() }}" - uses: "./.github/workflows/get-versions-builder.yaml" - with: - language: "python" - secrets: "inherit" - - check-julia: - if: "${{ always() }}" - needs: ["check-python"] - uses: "./.github/workflows/get-versions-builder.yaml" - with: - language: "julia" - secrets: "inherit" - - check-node: - if: "${{ always() }}" - needs: ["check-julia"] - uses: "./.github/workflows/get-versions-builder.yaml" - with: - language: "node" - secrets: "inherit" - - check-rbase: - if: "${{ always() }}" - needs: ["check-node"] - uses: "./.github/workflows/get-versions-builder.yaml" - with: - language: "rbase" - secrets: "inherit" - - compute-versions: - if: "${{ always() }}" - needs: ["check-rbase",] - runs-on: "ubuntu-latest" - steps: - - id: "checkout" - name: "Checkout `containers` repository" - uses: "actions/checkout@v3" - with: - fetch-depth: 0 - - - id: "checkout-HEAD" - run: | - git pull - git checkout HEAD - - - id: "setup-node" - name: "Setup NodeJS" - uses: "actions/setup-node@v3" - with: - node-version: "18" - - - id: "setup-pnpm" - name: "Setup `pnpm`" - uses: "pnpm/action-setup@v2" - with: - version: "latest" - run_install: false - - - name: "Get `pnpm` store" - id: "pnpm-store" - shell: "bash" - run: | - echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT - - - uses: "actions/cache@v3" - id: "pnpm-cache" - name: "Setup `pnpm` cache" - with: - path: "${{ steps.pnpm-store.outputs.STORE_PATH }}" - key: "${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}" - restore-keys: | - ${{ runner.os }}-pnpm-store- - - - name: "Install dependencies" - id: "pnpm-install" - run: "pnpm install" - - - name: "Computes all version pairings for Dockerfile" - run: | - pnpm compute-versions - - - name: "Add `docker.d/**/Dockerfile`" - uses: "endbug/add-and-commit@v9" - with: - add: | - ./docker.d/**/Dockerfile - ./versions.d/docker-versions.json - message: "Tracking `docker.d/**/Dockerfile` for verbosity" - push: true