├── .devcontainer.json ├── .github ├── dependabot.yml └── workflows │ ├── release-keyring.yaml │ ├── release.yaml │ ├── test-all.yaml │ ├── test-keyring.yaml │ └── test-pr.yaml ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── src ├── artifacts-helper │ ├── NOTES.md │ ├── README.md │ ├── codespaces_artifacts_helper_keyring │ │ ├── .gitignore │ │ ├── README.md │ │ ├── noxfile.py │ │ ├── pdm.lock │ │ ├── pyproject.toml │ │ ├── src │ │ │ └── codespaces_artifacts_helper_keyring │ │ │ │ ├── __init__.py │ │ │ │ ├── artifacts_helper_credential_provider.py │ │ │ │ └── keyring_backend.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── test_artifacts_helper_credential_provider.py │ │ │ └── test_keyring_backend.py │ ├── devcontainer-feature.json │ ├── install.sh │ └── scripts │ │ ├── install-provider.sh │ │ ├── install-python-keyring.sh │ │ ├── run-dotnet.sh │ │ ├── run-npm.sh │ │ ├── run-npx.sh │ │ ├── run-nuget.sh │ │ ├── run-pnpm.sh │ │ ├── run-pnpx.sh │ │ ├── run-rush-pnpm.sh │ │ ├── run-rush.sh │ │ ├── run-yarn.sh │ │ └── write-npm.sh ├── devtool │ ├── NOTES.md │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh ├── docfx │ ├── NOTES.md │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh ├── external-repository │ ├── NOTES.md │ ├── README.md │ ├── devcontainer-feature.json │ ├── install.sh │ └── scripts │ │ ├── ado-git.config │ │ ├── clone.sh │ │ ├── commit-msg.sh │ │ ├── external-git │ │ ├── prebuild-git.config │ │ ├── setup-user.sh │ │ ├── usersecret-git.config │ │ └── variables.sh ├── go │ ├── NOTES.md │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh └── microsoft-git │ ├── NOTES.md │ ├── README.md │ ├── devcontainer-feature.json │ └── install.sh └── test ├── _global ├── debian_tests.sh ├── mariner_tests.sh ├── scenarios.json └── ubuntu_tests.sh ├── artifacts-helper ├── check_python_and_keyring.sh ├── python312_and_keyring_debian.sh ├── python38_and_keyring_debian.sh ├── python38_and_keyring_ubuntu.sh ├── python_and_no_keyring.sh ├── scenarios.json └── test.sh ├── devtool └── test.sh ├── docfx └── test.sh ├── external-repository ├── README.md ├── basic-install.sh ├── branch-install.sh ├── multi-install.sh ├── options-install.sh ├── scalar-basic.sh ├── scalar-folder.sh ├── scalar-no-src.sh ├── scenarios.json ├── sparse-test.sh ├── telemetry-email.sh ├── telemetry-msg.sh ├── telemetry-name.sh └── test.sh ├── go ├── install_go_tool_in_postCreate.sh ├── install_go_twice.sh ├── install_mariner.sh ├── scenarios.json └── test.sh └── microsoft-git └── test.sh /.devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", 3 | "customizations": { 4 | "vscode": { 5 | "extensions": [ 6 | "mads-hartmann.bash-ide-vscode", 7 | "GitHub.copilot" 8 | ] 9 | } 10 | }, 11 | "features": { 12 | "ghcr.io/devcontainers/features/docker-in-docker:2": {} 13 | }, 14 | "remoteUser": "node", 15 | "postCreateCommand": "npm install -g @devcontainers/cli" 16 | } 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "weekly" -------------------------------------------------------------------------------- /.github/workflows/release-keyring.yaml: -------------------------------------------------------------------------------- 1 | name: Artifacts Helper Keyring Releases 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | 10 | defaults: 11 | run: 12 | working-directory: src/artifacts-helper/codespaces_artifacts_helper_keyring 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - uses: wntrblm/nox@main 18 | with: 19 | python-versions: "3.11, 3.12" 20 | 21 | - name: Setup PDM 22 | uses: pdm-project/setup-pdm@v4 23 | with: 24 | version: "2.15.1" 25 | python-version-file: "src/artifacts-helper/codespaces_artifacts_helper_keyring/pyproject.toml" 26 | 27 | - name: Run nox release 28 | run: pdm release 29 | 30 | - name: Upload build artifacts 31 | uses: actions/upload-artifact@v4 32 | with: 33 | name: codespaces_artifacts_helper_keyring 34 | path: | 35 | src/artifacts-helper/codespaces_artifacts_helper_keyring/dist 36 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: "Release dev container features & Generate Documentation" 2 | on: 3 | workflow_dispatch: 4 | 5 | 6 | jobs: 7 | deploy: 8 | if: ${{ github.ref == 'refs/heads/main' }} 9 | runs-on: ubuntu-latest 10 | permissions: 11 | contents: write 12 | packages: write 13 | pull-requests: write 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: "Publish Features" 18 | uses: devcontainers/action@v1 19 | with: 20 | publish-features: "true" 21 | base-path-to-features: "./src" 22 | generate-docs: "true" 23 | 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | 27 | - name: Create PR for Documentation 28 | id: push_image_info 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.RELEASE_FEATURE }} 31 | run: | 32 | set -e 33 | echo "Start." 34 | # Configure git and Push updates 35 | git config --global user.email github-actions@github.com 36 | git config --global user.name github-actions 37 | git config pull.rebase false 38 | branch=automated-documentation-update-$GITHUB_RUN_ID 39 | git checkout -b $branch 40 | message='Automated documentation update' 41 | # Add / update and commit 42 | git add */**/README.md 43 | git commit -m 'Automated documentation update [skip ci]' || export NO_UPDATES=true 44 | # Push 45 | if [ "$NO_UPDATES" != "true" ] ; then 46 | git push origin "$branch" 47 | gh api \ 48 | --method POST \ 49 | -H "Accept: application/vnd.github+json" \ 50 | /repos/${GITHUB_REPOSITORY}/pulls \ 51 | -f title="$message" \ 52 | -f body="$message" \ 53 | -f head="$branch" \ 54 | -f base='main' 55 | fi 56 | -------------------------------------------------------------------------------- /.github/workflows/test-all.yaml: -------------------------------------------------------------------------------- 1 | name: "CI - Test All Features" 2 | on: 3 | push: 4 | branches: 5 | - main 6 | workflow_dispatch: 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | continue-on-error: true 12 | strategy: 13 | matrix: 14 | features: 15 | - artifacts-helper 16 | - devtool 17 | - docfx 18 | - external-repository 19 | - microsoft-git 20 | - go 21 | baseImage: 22 | - mcr.microsoft.com/devcontainers/base:ubuntu 23 | - mcr.microsoft.com/devcontainers/base:debian 24 | - mcr.microsoft.com/cbl-mariner/base/core:2.0 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - name: "Install latest devcontainer CLI" 29 | run: npm install -g @devcontainers/cli 30 | 31 | - name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'" 32 | run: devcontainer features test -f ${{ matrix.features }} -i ${{ matrix.baseImage }} . 33 | 34 | test-global: 35 | runs-on: ubuntu-latest 36 | continue-on-error: true 37 | steps: 38 | - uses: actions/checkout@v4 39 | 40 | - name: "Install latest devcontainer CLI" 41 | run: npm install -g @devcontainers/cli 42 | 43 | - name: "Testing global scenarios" 44 | run: devcontainer features test --global-scenarios-only . -------------------------------------------------------------------------------- /.github/workflows/test-keyring.yaml: -------------------------------------------------------------------------------- 1 | name: Artifacts Helper Keyring Tests 2 | 3 | on: 4 | push: 5 | paths: 6 | - ".github/workflows/test-keyring.yaml" 7 | - "src/artifacts-helper/codespaces_artifacts_helper_keyring/**" 8 | 9 | pull_request: 10 | branches: 11 | - main 12 | paths: 13 | - ".github/workflows/test-keyring.yaml" 14 | - "src/artifacts-helper/codespaces_artifacts_helper_keyring/**" 15 | 16 | defaults: 17 | run: 18 | working-directory: src/artifacts-helper/codespaces_artifacts_helper_keyring 19 | 20 | jobs: 21 | generate-jobs: 22 | name: Generate jobs 23 | runs-on: ubuntu-latest 24 | outputs: 25 | session: ${{ steps.set-matrix.outputs.session }} 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - uses: wntrblm/nox@main 30 | with: 31 | python-versions: "3.12" 32 | 33 | - id: set-matrix 34 | shell: bash 35 | run: echo session=$(nox --json -l --tags ci | jq -c '[.[].session]') | tee --append $GITHUB_OUTPUT 36 | 37 | checks: 38 | name: Session ${{ matrix.session }} 39 | needs: [generate-jobs] 40 | runs-on: ubuntu-latest 41 | strategy: 42 | fail-fast: false 43 | matrix: 44 | session: ${{ fromJson(needs.generate-jobs.outputs.session) }} 45 | steps: 46 | - uses: actions/checkout@v4 47 | 48 | - uses: wntrblm/nox@main 49 | with: 50 | python-versions: "3.8, 3.9, 3.10, 3.11, 3.12, pypy-3.9, pypy-3.10" 51 | 52 | - name: Setup PDM 53 | uses: pdm-project/setup-pdm@v4 54 | with: 55 | version: "2.15.1" 56 | python-version-file: "src/artifacts-helper/codespaces_artifacts_helper_keyring/pyproject.toml" 57 | 58 | - name: Run ${{ matrix.session }} 59 | run: pdm run nox --error-on-missing-interpreters --error-on-external-run -s "${{ matrix.session }}" 60 | -------------------------------------------------------------------------------- /.github/workflows/test-pr.yaml: -------------------------------------------------------------------------------- 1 | name: "PR - Test Updated Features" 2 | on: 3 | pull_request: 4 | 5 | jobs: 6 | detect-changes: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | contents: read 10 | pull-requests: read 11 | outputs: 12 | features: ${{ steps.filter.outputs.changes }} 13 | steps: 14 | - uses: dorny/paths-filter@v3 15 | id: filter 16 | with: 17 | filters: | 18 | artifacts-helper: ./**/artifacts-helper/** 19 | devtool: ./**/devtool/** 20 | docfx: ./**/docfx/** 21 | external-repository: ./**/external-repository/** 22 | microsoft-git: ./**/microsoft-git/** 23 | go: ./**/go/** 24 | test: 25 | needs: [detect-changes] 26 | runs-on: ubuntu-latest 27 | continue-on-error: true 28 | strategy: 29 | matrix: 30 | features: ${{ fromJSON(needs.detect-changes.outputs.features) }} 31 | baseImage: 32 | [ 33 | "mcr.microsoft.com/devcontainers/base:ubuntu", 34 | "mcr.microsoft.com/devcontainers/base:debian", 35 | "mcr.microsoft.com/cbl-mariner/base/core:2.0", 36 | ] 37 | steps: 38 | - uses: actions/checkout@v4 39 | 40 | - name: "Install latest devcontainer CLI" 41 | run: npm install -g @devcontainers/cli 42 | 43 | - name: "Generating tests for '${{ matrix.features }}' against '${{ matrix.baseImage }}'" 44 | run: devcontainer features test --skip-scenarios -f ${{ matrix.features }} -i ${{ matrix.baseImage }} . 45 | 46 | test-scenarios: 47 | needs: [detect-changes] 48 | runs-on: ubuntu-latest 49 | continue-on-error: true 50 | strategy: 51 | matrix: 52 | features: ${{ fromJSON(needs.detect-changes.outputs.features) }} 53 | steps: 54 | - uses: actions/checkout@v4 55 | 56 | - name: "Install latest devcontainer CLI" 57 | run: npm install -g @devcontainers/cli 58 | 59 | - name: "Testing '${{ matrix.features }}' scenarios" 60 | run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated . -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Codespace Features 2 | 3 | 4 | This is a repository of [devcontainer features](https://containers.dev/implementors/features/) 5 | to assist teams in adopting Codespaces. Here is a list of the features in this repository: 6 | 7 | | Feature | Description | 8 | | ------- | ----------- | 9 | | [artifacts-helper](src/artifacts-helper) | Install Azure Artifacts credential helper configured for Codespace authentication | 10 | | [devtool](src/devtool) | Installs DevTool (Microsoft-internal only) | 11 | | [docfx](src/docfx) | Install docfx to support editing and testing documentation | 12 | | [external-repository](src/external-repository) | Handles all the details of working with an external git repository in Codespaces | 13 | | [microsoft-git](src/microsoft-git) | Install microsoft/git with Scalar and GVFS support | 14 | | [go](src/go) | Install go (with support for Mariner) | 15 | 16 | ## Contributing 17 | 18 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 19 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 20 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 21 | 22 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 23 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 24 | provided by the bot. You will only need to do this once across all repos using our CLA. 25 | 26 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 27 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 28 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 29 | 30 | ## Trademarks 31 | 32 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 33 | trademarks or logos is subject to and must follow 34 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 35 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 36 | Any use of third-party trademarks or logos are subject to those third-party's policies. 37 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support 2 | 3 | ## How to file issues and get help 4 | 5 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 6 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 7 | feature request as a new Issue. 8 | 9 | For help and questions about using this project, please use our [Discussions](https://github.com/microsoft/codespace-features/discussions) 10 | 11 | ## Microsoft Support Policy 12 | 13 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 14 | -------------------------------------------------------------------------------- /src/artifacts-helper/NOTES.md: -------------------------------------------------------------------------------- 1 | This installs [Azure Artifacts Credential Provider](https://github.com/microsoft/artifacts-credprovider) 2 | and optionally configures functions which shadow `dotnet`, `nuget`, `npm`, `yarn`, `rush`, and `pnpm` which dynamically sets an authentication token 3 | for pulling artifacts from a feed before running the command. 4 | 5 | For `npm`, `yarn`, `rush`, and `pnpm` this requires that your `~/.npmrc` file is configured to use the ${ARTIFACTS_ACCESSTOKEN} 6 | environment variable for the `authToken`. A helper script has been added that you can use to write your `~/.npmrc` 7 | file during your setup process, though there are many ways you could accomplish this. To use the script, run it like 8 | this: 9 | 10 | ``` 11 | write-npm.sh pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm 12 | write-npm.sh pkgs.dev.azure.com/orgname/projectname/_packaging/feed2/npm username 13 | write-npm.sh pkgs.dev.azure.com/orgname/projectname/_packaging/feed3/npm username email 14 | ``` 15 | 16 | You must pass the feed name to the script, but you can optionally provide a username and email if desired. Defaults 17 | are put in place if they are not provided. An example of the `.npmrc` file created is this: 18 | 19 | ``` 20 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/registry/:username=codespaces 21 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/registry/:_authToken=${ARTIFACTS_ACCESSTOKEN} 22 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/registry/:email=codespaces@github.com 23 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/:username=codespaces 24 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/:_authToken=${ARTIFACTS_ACCESSTOKEN} 25 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/:email=codespaces@github.com 26 | ``` 27 | 28 | ## Python Keyring Helper 29 | 30 | Add the optional `{ "python" : true }` to install a Python Keyring helper that will handle authentication 31 | to Python feeds using the same mechanism as the other languages. To install a package just run something 32 | like: 33 | 34 | ``` 35 | pip install --index-url https://pkgs.dev.azure.com//_packaging//pypi/simple 36 | ``` 37 | 38 | When the feed URL is an Azure Artifacts feed pip will use the keyring helper to provide the credentials needed 39 | to download the package. 40 | 41 | ## OS Support 42 | 43 | This feature is tested to work on Debian/Ubuntu and Mariner CBL 2.0 44 | 45 | ## Changing where functions are configured 46 | 47 | By default, the functions are defined in `/etc/bash.bashrc` and `/etc/zsh/zshrc` if the container user is `root`, otherwise `~/.bashrc` and `~/.zshrc`. 48 | This default configuration ensures that the functions are always available for any interactive shells. 49 | 50 | In some cases it can be useful to have the functions written to a non-default location. For example: 51 | - the configuration file of a shell other than `bash` and `zsh` 52 | - a custom file which is not a shell configuration script (so that it can be `source`d in non-interactive shells and scripts) 53 | 54 | To do this, set the `targetFiles` option to the path script path where the functions should be written. Note that the default paths WILL NOT be used 55 | if the `targetFiles` option is provided, so you may want to include them in the overridden value, or add `source` the custom script in those configurations: 56 | 57 | ```bash 58 | # .devcontainer/devcontainer.json 59 | { 60 | // ... 61 | "targetFiles": "/custom/path/to/auth-helper.sh" 62 | } 63 | 64 | # ~/.bashrc 65 | 66 | source /custom/path/to/auth-helper.sh 67 | ``` -------------------------------------------------------------------------------- /src/artifacts-helper/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Azure Artifacts Credential Helper (artifacts-helper) 3 | 4 | Configures Codespace to authenticate with Azure Artifact feeds 5 | 6 | ## Example Usage 7 | 8 | ```json 9 | "features": { 10 | "ghcr.io/microsoft/codespace-features/artifacts-helper:2": {} 11 | } 12 | ``` 13 | 14 | ## Options 15 | 16 | | Options Id | Description | Type | Default Value | 17 | |-----|-----|-----|-----| 18 | | nugetURIPrefixes | Nuget URI Prefixes | string | https://pkgs.dev.azure.com/ | 19 | | dotnet6 | Use .NET 6 Runtime | boolean | false | 20 | | dotnetAlias | Create alias for dotnet | boolean | true | 21 | | nugetAlias | Create alias for nuget | boolean | true | 22 | | npmAlias | Create alias for npm | boolean | true | 23 | | yarnAlias | Create alias for yarn | boolean | true | 24 | | npxAlias | Create alias for npx | boolean | true | 25 | | rushAlias | Create alias for rush | boolean | true | 26 | | pnpmAlias | Create alias for pnpm | boolean | true | 27 | | targetFiles | Comma separated list of files to write to. Default is '/etc/bash.bashrc,/etc/zsh/zshrc' for root and '~/.bashrc,~/.zshrc' for non-root | string | DEFAULT | 28 | | python | Install Python keyring helper for pip | boolean | false | 29 | 30 | ## Customizations 31 | 32 | ### VS Code Extensions 33 | 34 | - `ms-codespaces-tools.ado-codespaces-auth` 35 | 36 | This installs [Azure Artifacts Credential Provider](https://github.com/microsoft/artifacts-credprovider) 37 | and optionally configures functions which shadow `dotnet`, `nuget`, `npm`, `yarn`, `rush`, and `pnpm` which dynamically sets an authentication token 38 | for pulling artifacts from a feed before running the command. 39 | 40 | For `npm`, `yarn`, `rush`, and `pnpm` this requires that your `~/.npmrc` file is configured to use the ${ARTIFACTS_ACCESSTOKEN} 41 | environment variable for the `authToken`. A helper script has been added that you can use to write your `~/.npmrc` 42 | file during your setup process, though there are many ways you could accomplish this. To use the script, run it like 43 | this: 44 | 45 | ``` 46 | write-npm.sh pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm 47 | write-npm.sh pkgs.dev.azure.com/orgname/projectname/_packaging/feed2/npm username 48 | write-npm.sh pkgs.dev.azure.com/orgname/projectname/_packaging/feed3/npm username email 49 | ``` 50 | 51 | You must pass the feed name to the script, but you can optionally provide a username and email if desired. Defaults 52 | are put in place if they are not provided. An example of the `.npmrc` file created is this: 53 | 54 | ``` 55 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/registry/:username=codespaces 56 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/registry/:_authToken=${ARTIFACTS_ACCESSTOKEN} 57 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/registry/:email=codespaces@github.com 58 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/:username=codespaces 59 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/:_authToken=${ARTIFACTS_ACCESSTOKEN} 60 | //pkgs.dev.azure.com/orgname/projectname/_packaging/feed1/npm/:email=codespaces@github.com 61 | ``` 62 | 63 | ## Python Keyring Helper 64 | 65 | Add the optional `{ "python" : true }` to install a Python Keyring helper that will handle authentication 66 | to Python feeds using the same mechanism as the other languages. To install a package just run something 67 | like: 68 | 69 | ``` 70 | pip install --index-url https://pkgs.dev.azure.com//_packaging//pypi/simple 71 | ``` 72 | 73 | When the feed URL is an Azure Artifacts feed pip will use the keyring helper to provide the credentials needed 74 | to download the package. 75 | 76 | ## OS Support 77 | 78 | This feature is tested to work on Debian/Ubuntu and Mariner CBL 2.0 79 | 80 | ## Changing where functions are configured 81 | 82 | By default, the functions are defined in `/etc/bash.bashrc` and `/etc/zsh/zshrc` if the container user is `root`, otherwise `~/.bashrc` and `~/.zshrc`. 83 | This default configuration ensures that the functions are always available for any interactive shells. 84 | 85 | In some cases it can be useful to have the functions written to a non-default location. For example: 86 | - the configuration file of a shell other than `bash` and `zsh` 87 | - a custom file which is not a shell configuration script (so that it can be `source`d in non-interactive shells and scripts) 88 | 89 | To do this, set the `targetFiles` option to the path script path where the functions should be written. Note that the default paths WILL NOT be used 90 | if the `targetFiles` option is provided, so you may want to include them in the overridden value, or add `source` the custom script in those configurations: 91 | 92 | ```bash 93 | # .devcontainer/devcontainer.json 94 | { 95 | // ... 96 | "targetFiles": "/custom/path/to/auth-helper.sh" 97 | } 98 | 99 | # ~/.bashrc 100 | 101 | source /custom/path/to/auth-helper.sh 102 | ``` 103 | 104 | --- 105 | 106 | _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/microsoft/codespace-features/blob/main/src/artifacts-helper/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ 107 | -------------------------------------------------------------------------------- /src/artifacts-helper/codespaces_artifacts_helper_keyring/.gitignore: -------------------------------------------------------------------------------- 1 | ### Python ### 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | cover/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # poetry 99 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 100 | # This is especially recommended for binary packages to ensure reproducibility, and is more 101 | # commonly ignored for libraries. 102 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 103 | #poetry.lock 104 | 105 | # pdm 106 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 107 | #pdm.lock 108 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 109 | # in version control. 110 | # https://pdm.fming.dev/#use-with-ide 111 | .pdm.toml 112 | 113 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 114 | __pypackages__/ 115 | 116 | # Celery stuff 117 | celerybeat-schedule 118 | celerybeat.pid 119 | 120 | # SageMath parsed files 121 | *.sage.py 122 | 123 | # Environments 124 | .env 125 | .venv 126 | env/ 127 | venv/ 128 | ENV/ 129 | env.bak/ 130 | venv.bak/ 131 | 132 | # Spyder project settings 133 | .spyderproject 134 | .spyproject 135 | 136 | # Rope project settings 137 | .ropeproject 138 | 139 | # mkdocs documentation 140 | /site 141 | 142 | # mypy 143 | .mypy_cache/ 144 | .dmypy.json 145 | dmypy.json 146 | 147 | # Pyre type checker 148 | .pyre/ 149 | 150 | # pytype static type analyzer 151 | .pytype/ 152 | 153 | # Cython debug symbols 154 | cython_debug/ 155 | 156 | # PyCharm 157 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 158 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 159 | # and can be added to the global gitignore or merged into this file. For a more nuclear 160 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 161 | #.idea/ 162 | 163 | ### Python Patch ### 164 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration 165 | poetry.toml 166 | 167 | # ruff 168 | .ruff_cache/ 169 | 170 | # LSP config files 171 | pyrightconfig.json 172 | 173 | # PDM 174 | .pdm-python 175 | 176 | ### macOS ### 177 | # General 178 | .DS_Store 179 | .AppleDouble 180 | .LSOverride 181 | 182 | # Icon must end with two \r 183 | Icon 184 | 185 | # Thumbnails 186 | ._* 187 | 188 | # Files that might appear in the root of a volume 189 | .DocumentRevisions-V100 190 | .fseventsd 191 | .Spotlight-V100 192 | .TemporaryItems 193 | .Trashes 194 | .VolumeIcon.icns 195 | .com.apple.timemachine.donotpresent 196 | 197 | # Directories potentially created on remote AFP share 198 | .AppleDB 199 | .AppleDesktop 200 | Network Trash Folder 201 | Temporary Items 202 | .apdisk 203 | 204 | ### macOS Patch ### 205 | # iCloud generated files 206 | *.icloud 207 | 208 | ### Windows ### 209 | # Windows thumbnail cache files 210 | Thumbs.db 211 | Thumbs.db:encryptable 212 | ehthumbs.db 213 | ehthumbs_vista.db 214 | 215 | # Dump file 216 | *.stackdump 217 | 218 | # Folder config file 219 | [Dd]esktop.ini 220 | 221 | # Recycle Bin used on file shares 222 | $RECYCLE.BIN/ 223 | -------------------------------------------------------------------------------- /src/artifacts-helper/codespaces_artifacts_helper_keyring/README.md: -------------------------------------------------------------------------------- 1 | # codespaces_artifacts_helper_keyring 2 | 3 | The `codespaces_artifacts_helper_keyring` package provides [keyring](https://pypi.org/project/keyring) authentication for consuming Python packages from Azure Artifacts feeds using the [Codespaces Artifacts Helper](https://github.com/microsoft/codespace-features/tree/main/src/artifacts-helper) and its underlying authentication tool, [ado-codespaces-auth](https://github.com/microsoft/ado-codespaces-auth). 4 | 5 | This package is an extension to [keyring](https://pypi.org/project/keyring), which will automatically find and use it once installed. Both [pip](https://pypi.org/project/pip) and [twine](https://pypi.org/project/twine) will use keyring to find credentials. 6 | 7 | ## Installation 8 | 9 | ### From Source 10 | 11 | To install this package from source: 12 | 13 | ```sh 14 | $ cd src/artifacts-helper/codespaces_artifacts_helper_keyring 15 | 16 | # PDM is used to manage the project 17 | $ pip install 'pdm>=2.14' 18 | 19 | # Install dependencies and build the package 20 | $ pdm build 21 | 22 | # Install package and dependencies with pip 23 | $ pip install dist/codespaces_artifacts_helper_keyring-*.whl 24 | ``` 25 | 26 | ### From GitHub Releases 27 | 28 | TODO: Write instructions 29 | 30 | ## Usage 31 | 32 | ### Requirements 33 | 34 | To use `codespaces_artifacts_helper_keyring` to set up authentication between `pip` and Azure Artifacts, the following requirements must be met: 35 | 36 | - pip version **19.2** or higher 37 | - python version **3.8** or higher 38 | - running inside a Codespace with [Codespaces Artifacts Helper](https://github.com/microsoft/codespace-features/tree/main/src/artifacts-helper) and the `param` option set to `true`. This will automatically install the `codespaces_artifacts_helper_keyring` package for you. 39 | ```json 40 | { 41 | "features": { 42 | "ghcr.io/microsoft/codespace-features/artifacts-helper:1": { 43 | "python": true 44 | } 45 | } 46 | } 47 | ``` 48 | 49 | ### Inner Workings 50 | 51 | The `codespaces_artifacts_helper_keyring` will detect if the package index has a domain that matches Azure Artifacts, e.g. `pkgs.dev.azure.com`. If it does, it will use the `ado-codespaces-auth` tool at `~/ado-auth-helper` to fetch an access token. This token will be used to authenticate with the Azure Artifacts feed. 52 | 53 | ### Installing Packages from an Azure Artifacts Feed 54 | 55 | Once the codespace is ready, to consume a package, use the following `pip` command, replacing **** and **** with your own, and **** with the package you want to install: 56 | 57 | ``` 58 | pip install --index-url https://pkgs.dev.azure.com//_packaging//pypi/simple 59 | ``` 60 | 61 | ## Contributing 62 | 63 | We use [PDM](https://pdm-project.org/) to manage the project and its dependencies. To get started, install PDM: 64 | 65 | ```sh 66 | $ pip install 'pdm>=2.14' 67 | ``` 68 | 69 | Then, install the project dependencies: 70 | 71 | ```sh 72 | $ pdm install 73 | ``` 74 | 75 | ### Scripts 76 | 77 | A set of scripts are in `pyproject.toml` to help with common tasks. These can be run using `pdm