diff --git a/.github/workflows/test-all.yaml b/.github/workflows/test-all.yaml index dd1d216a0..3d4aa3fed 100644 --- a/.github/workflows/test-all.yaml +++ b/.github/workflows/test-all.yaml @@ -50,6 +50,19 @@ jobs: "mcr.microsoft.com/devcontainers/base:debian", "mcr.microsoft.com/devcontainers/base:noble" ] + exclude: + - features: oryx + baseImage: ubuntu:jammy + - features: oryx + baseImage: mcr.microsoft.com/devcontainers/base:ubuntu + - features: docker-in-docker + baseImage: mcr.microsoft.com/devcontainers/base:debian + - features: docker-outside-of-docker + baseImage: mcr.microsoft.com/devcontainers/base:debian + - features: docker-in-docker + baseImage: mcr.microsoft.com/devcontainers/base:ubuntu + - features: docker-outside-of-docker + baseImage: mcr.microsoft.com/devcontainers/base:ubuntu steps: - uses: actions/checkout@v7 @@ -100,6 +113,15 @@ jobs: - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli + - name: "Exclude iptables-isolation scenarios from docker-in-docker (run in separate 'iptables-isolation' job)" + if: matrix.features == 'docker-in-docker' + run: | + sudo apt-get update && sudo apt-get install -y jq + sed 's://.*$::' test/docker-in-docker/scenarios.json \ + | jq 'del(.docker_with_default_iptables, .docker_with_default_iptables_ubuntu)' \ + > test/docker-in-docker/scenarios.json.tmp + mv test/docker-in-docker/scenarios.json.tmp test/docker-in-docker/scenarios.json + - name: "Testing '${{ matrix.features }}' scenarios" run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated . diff --git a/.github/workflows/update-aws-cli-completer-scripts.yml b/.github/workflows/update-aws-cli-completer-scripts.yml index fde3a29fc..eeec43475 100644 --- a/.github/workflows/update-aws-cli-completer-scripts.yml +++ b/.github/workflows/update-aws-cli-completer-scripts.yml @@ -9,10 +9,20 @@ jobs: runs-on: ubuntu-latest environment: documentation # grants access to secrets.PAT, for creating pull requests permissions: - contents: write - pull-requests: write + contents: read steps: - - uses: actions/checkout@v7 + - name: Generate a token + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ vars.DEVCONTAINERS_REPO_AUTOMATION_ID }} + private-key: ${{ secrets.DEVCONTAINERS_REPO_AUTOMATION_PRIVATE_KEY }} + + - name: Checkout + id: checkout + uses: actions/checkout@v7 + with: + token: ${{ steps.app-token.outputs.token }} - name: Run fetch-latest-completer-scripts.sh run: src/aws-cli/scripts/fetch-latest-completer-scripts.sh @@ -20,7 +30,7 @@ jobs: - name: Create a PR for completer scripts id: push_image_info env: - GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} run: | set -e echo "Start." diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml index 50a643fd7..e5023ccb3 100644 --- a/.github/workflows/update-documentation.yml +++ b/.github/workflows/update-documentation.yml @@ -10,11 +10,21 @@ jobs: runs-on: ubuntu-latest environment: documentation permissions: - contents: write - pull-requests: write + contents: read if: "github.ref == 'refs/heads/main'" steps: - - uses: actions/checkout@v7 + - name: Generate a token + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ vars.DEVCONTAINERS_REPO_AUTOMATION_ID }} + private-key: ${{ secrets.DEVCONTAINERS_REPO_AUTOMATION_PRIVATE_KEY }} + + - name: Checkout + id: checkout + uses: actions/checkout@v7 + with: + token: ${{ steps.app-token.outputs.token }} - name: Generate Documentation uses: devcontainers/action@v1 @@ -25,7 +35,7 @@ jobs: - name: Create a PR for Documentation id: push_image_info env: - GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} run: | set -e echo "Start." diff --git a/.github/workflows/update-dotnet-install-script.yml b/.github/workflows/update-dotnet-install-script.yml index 16f737ff2..d8f532d9d 100644 --- a/.github/workflows/update-dotnet-install-script.yml +++ b/.github/workflows/update-dotnet-install-script.yml @@ -9,10 +9,20 @@ jobs: runs-on: ubuntu-latest environment: documentation # grants access to secrets.PAT, for creating pull requests permissions: - contents: write - pull-requests: write + contents: read steps: - - uses: actions/checkout@v7 + - name: Generate a token + id: app-token + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ vars.DEVCONTAINERS_REPO_AUTOMATION_ID }} + private-key: ${{ secrets.DEVCONTAINERS_REPO_AUTOMATION_PRIVATE_KEY }} + + - name: Checkout + id: checkout + uses: actions/checkout@v7 + with: + token: ${{ steps.app-token.outputs.token }} - name: Run fetch-latest-dotnet-install.sh run: src/dotnet/scripts/fetch-latest-dotnet-install.sh @@ -20,7 +30,7 @@ jobs: - name: Create a PR for dotnet-install.sh id: push_image_info env: - GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_TOKEN: ${{ steps.app-token.outputs.token }} run: | set -e echo "Start." diff --git a/src/github-cli/NOTES.md b/src/github-cli/NOTES.md index e742805e6..53c5322dd 100644 --- a/src/github-cli/NOTES.md +++ b/src/github-cli/NOTES.md @@ -6,4 +6,6 @@ This Feature should work on recent versions of Debian/Ubuntu-based distributions ## Extensions -If you set the `extensions` option, the feature will run `gh extension install` for each entry (comma-separated). Extensions are installed for the most appropriate non-root user (based on `USERNAME` / `_REMOTE_USER`), with a fallback to `root`. +If you set the `extensions` option, the feature will install each comma-separated entry. Extensions are installed for the most appropriate non-root user (based on `USERNAME` / `_REMOTE_USER`), with a fallback to `root`. + +Private extensions can be installed when `GH_TOKEN` or `GITHUB_TOKEN` is available during feature installation. The token is forwarded to the selected non-root user and used through the GitHub CLI Git credential helper. diff --git a/src/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index 15a91e43d..58b3e5b2f 100644 --- a/src/github-cli/devcontainer-feature.json +++ b/src/github-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "github-cli", - "version": "1.1.0", + "version": "1.1.1", "name": "GitHub CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/github-cli", "description": "Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies.", diff --git a/src/github-cli/install.sh b/src/github-cli/install.sh index e3eaba0c3..3638d9392 100755 --- a/src/github-cli/install.sh +++ b/src/github-cli/install.sh @@ -271,7 +271,11 @@ if [ -n "${EXTENSIONS}" ]; then else EXTENSIONS_ESCAPED="$(printf '%q' "${EXTENSIONS}")" USERNAME_ESCAPED="$(printf '%q' "${USERNAME}")" - su - "${USERNAME}" -c "EXTENSIONS=${EXTENSIONS_ESCAPED} USERNAME=${USERNAME_ESCAPED} INSTALL_EXTENSIONS=true bash '${EXTENSIONS_SCRIPT}'" + su \ + --login \ + --whitelist-environment=GH_TOKEN,GITHUB_TOKEN \ + --command "EXTENSIONS=${EXTENSIONS_ESCAPED} USERNAME=${USERNAME_ESCAPED} INSTALL_EXTENSIONS=true bash '${EXTENSIONS_SCRIPT}'" \ + "${USERNAME}" INSTALL_EXTENSIONS=false bash "${EXTENSIONS_SCRIPT}" fi fi diff --git a/src/github-cli/scripts/install-extensions.sh b/src/github-cli/scripts/install-extensions.sh index 436accf03..f8a893534 100644 --- a/src/github-cli/scripts/install-extensions.sh +++ b/src/github-cli/scripts/install-extensions.sh @@ -26,18 +26,32 @@ install_extension() { mkdir -p "${extensions_root}" if [ ! -d "${extensions_root}/${repo_name}" ]; then - git clone --depth 1 "https://github.com/${extension}.git" "${extensions_root}/${repo_name}" + git \ + -c credential.helper= \ + -c credential.helper='!gh auth git-credential' \ + clone --depth 1 "https://github.com/${extension}.git" "${extensions_root}/${repo_name}" fi } ensure_gh_extension_list_wrapper() { + local gh_config_dir + if [ "$(id -u)" -ne 0 ]; then return fi - if gh extension list >/dev/null 2>&1; then + gh_config_dir="$(mktemp -d)" + if env \ + -u GH_TOKEN \ + -u GITHUB_TOKEN \ + -u GH_ENTERPRISE_TOKEN \ + -u GITHUB_ENTERPRISE_TOKEN \ + GH_CONFIG_DIR="${gh_config_dir}" \ + gh extension list >/dev/null 2>&1; then + rm -rf "${gh_config_dir}" return fi + rm -rf "${gh_config_dir}" cat > /usr/local/bin/gh <<'EOF' #!/usr/bin/env bash diff --git a/src/terraform/README.md b/src/terraform/README.md index 4b37b4260..8cfb673dc 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -21,6 +21,7 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la | installSentinel | Install sentinel, a language and framework for policy built to be embedded in existing software to enable fine-grained, logic-based policy decisions | boolean | false | | installTFsec | Install tfsec, a tool to spot potential misconfigurations for your terraform code | boolean | false | | installTerraformDocs | Install terraform-docs, a utility to generate documentation from Terraform modules | boolean | false | +| terraformDocsVersion | terraform-docs version to install (only used when installTerraformDocs is true) (https://github.com/terraform-docs/terraform-docs/releases) | string | latest | | httpProxy | Connect to a keyserver using a proxy by configuring this option | string | - | | customDownloadServer | Custom server URL for downloading Terraform and Sentinel packages, including protocol (e.g., https://releases.hashicorp.com). If not provided, the default HashiCorp download server (https://releases.hashicorp.com) will be used. | string | - | diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 29d3efb30..634d865ef 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.4.5", + "version": "1.5.0", "name": "Terraform, tflint, and TFGrunt", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/terraform", "description": "Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects latest version and installs needed dependencies.", @@ -50,6 +50,16 @@ "default": false, "description": "Install terraform-docs, a utility to generate documentation from Terraform modules" }, + "terraformDocsVersion": { + "type": "string", + "proposals": [ + "latest", + "0.20.0", + "0.19.0" + ], + "default": "latest", + "description": "terraform-docs version to install (only used when installTerraformDocs is true) (https://github.com/terraform-docs/terraform-docs/releases)" + }, "httpProxy": { "type": "string", "default": "", diff --git a/src/terraform/install.sh b/src/terraform/install.sh index ef0c73e5d..43779f825 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -18,6 +18,7 @@ TERRAGRUNT_VERSION="${TERRAGRUNT:-"latest"}" INSTALL_SENTINEL=${INSTALLSENTINEL:-false} INSTALL_TFSEC=${INSTALLTFSEC:-false} INSTALL_TERRAFORM_DOCS=${INSTALLTERRAFORMDOCS:-false} +TERRAFORM_DOCS_VERSION="${TERRAFORMDOCSVERSION:-"latest"}" CUSTOM_DOWNLOAD_SERVER="${CUSTOMDOWNLOADSERVER:-""}" # This is because ubuntu noble, ubuntu resolute and debian trixie don't support the old format of GPG keys and validation NEW_GPG_CODENAMES="trixie noble resolute" @@ -641,7 +642,6 @@ install_terraform_docs() { } if [ "${INSTALL_TERRAFORM_DOCS}" = "true" ]; then - TERRAFORM_DOCS_VERSION="latest" terraform_docs_url='https://github.com/terraform-docs/terraform-docs' find_version_from_git_tags TERRAFORM_DOCS_VERSION $terraform_docs_url tfdocs_filename="terraform-docs-v${TERRAFORM_DOCS_VERSION}-linux-${architecture}.tar.gz" diff --git a/test/terraform/install_terraform_docs_version.sh b/test/terraform/install_terraform_docs_version.sh new file mode 100644 index 000000000..4a747f82e --- /dev/null +++ b/test/terraform/install_terraform_docs_version.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Check to make sure the user is vscode +check "user is vscode" whoami | grep vscode + +# Terraform Docs specific tests +check "terraform-docs" terraform-docs --version + +# Verify the pinned version was installed +check "terraform-docs version is pinned to 0.20.0" bash -c "terraform-docs --version | grep 'v0.20.0'" + +# Report result +reportResults diff --git a/test/terraform/scenarios.json b/test/terraform/scenarios.json index 796efbd3e..de897b5e9 100644 --- a/test/terraform/scenarios.json +++ b/test/terraform/scenarios.json @@ -79,6 +79,15 @@ } } }, + "install_terraform_docs_version": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "terraform": { + "installTerraformDocs": true, + "terraformDocsVersion": "0.20.0" + } + } + }, "terraform_docs_fallback_test": { "image": "mcr.microsoft.com/devcontainers/base:jammy", "features": {