Giter Club home page Giter Club logo

features's People

Contributors

andres-rojas avatar arrrgi avatar artecoids avatar ccavolt avatar cgrothaus avatar codebytes avatar codeman99 avatar colinaaa avatar daneweber avatar danielbraun89 avatar dbrtly avatar ebaskoro avatar github-actions[bot] avatar gremo avatar gund avatar jcbhmr avatar m-dango avatar natescherer avatar nikaro avatar nozil avatar ovirs avatar pdcalado avatar ross-p-smith avatar rugk avatar ryanmerolle avatar scottcwang avatar shikanime avatar tom-fletcher avatar tomharvey avatar yf-yang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

features's Issues

localstack failing build Action

Right now the localstack feature is failing its tests (as of the latest commit at time of writing).

Image of the failed Action

image

image

The error message that kills the build process is:

AttributeError: module 'distutils.log' has no attribute 'warning'. Did you mean: 'warnings'?

Link to it in the Actions log

The most relevant result from Google seems to be: pypa/setuptools#3707. Here's the PR that supposedly fixes the issue: pypa/setuptools#3709. I don't know what the fix would be. Maybe this is just some issue upstream that will eventually go away?

Better user documentation

Right now things don't look to great when you wind up on the repo home page.

To change this, I think that these things could be done:

  • Add a header image #68
  • Add a more descriptive description #68
  • Add a "how to use" section #68
  • Add a CONTRIBUTING.md guide #68
  • Add details on how to add a new feature Moved to another "better contributor docs" issue #77

Haskell Extension Pack does not work without additional steps

I'm looking to create further PRs for the Haskell Feature, but before I do I want to check that I'm on the right path.

Is editing the install.sh and devcontainer-feature.json files directly in this repo the right approach? I observed a conversation about cookie cutter and generating these files, but I'm not sure I'm following the vision for the future.

I'm new to Haskell and learning a little bit of it through Exercism. I want to try it out in a container in VS Code using what appear to be the most popular plug-ins, the Haskell Extension Pack. Does it fit with the design goals for this repo for me to add steps and change defaults so that the base Haskell Feature supports the following scenario?

  1. Open a fresh directory with a simple "Hello World" Haskell program in VS Code.
  2. Execute the Add Dev Container Configuration Files command
  3. Choose Ubuntu with the default jammy version.
  4. Add the Haskell Feature listed.
  5. Select Reopen in Container.
  6. Find the "Haskell Extension Pack" extension and choose to Install it in the Dev Container.
  7. Open the HelloWorld.hs file and benefit from the extensions without further action needed.

At present, when I complete the steps above, I see a prompt to download hls-1.8.0.0 and also that hlint cannot be found.

image

Agreeing to install HLS results in further errors because of version mismatches.

image

I didn't save my steps, but I got everything working previously and believe I can set up the Haskell Feature to run these extensions out of the box.

@danielbraun89, before I do so: is that a desirable set of changes? If it affects your answer, I'm also planning to do something similar for additional languages that have Exercism tracks (such as Clojure, Elixir, and Scala).

GitHub Codespaces failing

I am completely clueless. I don't know if this is on me, or on the configuration. Looking for a second set of eyes.

I was attempting to pull up a GitHub Codespaces instance to demonstrate the process for the developer-focused wiki (a "Getting started with GitHub Codespaces" section), and ran into the fact that I couldn't get it to work!

The error that kills it is:

write /home/codespace/.local/lib/python3.10/site-packages/torch/lib/libtorch_cpu.so: no space left on device
Full error log
=================================================================================
2022-11-29 22:02:58.678Z: Configuration starting...
2022-11-29 22:02:58.720Z: Cloning...
2022-11-29 22:02:58.738Z: $ git -C "/var/lib/docker/codespacemount/workspace" clone --branch main --depth 1 https://github.com/devcontainers-contrib/features "/var/lib/docker/codespacemount/workspace/features"
2022-11-29 22:02:58.744Z: Cloning into '/var/lib/docker/codespacemount/workspace/features'...
2022-11-29 22:02:59.096Z: git process exited with exit code 0
2022-11-29 22:02:59.105Z: $ git -C "/var/lib/docker/codespacemount/workspace/features" config --local remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
2022-11-29 22:02:59.111Z: git process exited with exit code 0
2022-11-29 22:02:59.451Z: Using image: mcr.microsoft.com/devcontainers/universal:2

2022-11-29 22:05:55.117Z: #11 ERROR: failed to register layer: ApplyLayer exit status 1 stdout:  stderr: write /home/codespace/.local/lib/python3.10/site-packages/torch/lib/libtorch_cpu.so: no space left on device
2022-11-29 22:05:55.117Z: 
2022-11-29 22:05:55.117Z: #8 [internal] load metadata for mcr.microsoft.com/devcontainers/universal:linux
2022-11-29 22:05:55.117Z: 
2022-11-29 22:05:55.117Z: ------
2022-11-29 22:05:55.117Z: 
2022-11-29 22:05:55.117Z:  > [dev_containers_feature_content_normalize 1/3] FROM mcr.microsoft.com/devcontainers/universal:linux@sha256:5860442949e556cd1ef53ccfa8d45b0a82d09e78910a46a011aa30a769380102:
2022-11-29 22:05:55.117Z: 
2022-11-29 22:05:55.117Z: ------
2022-11-29 22:05:55.117Z: 
2022-11-29 22:05:55.144Z: ERROR: failed to solve: failed to register layer: ApplyLayer exit status 1 stdout:  stderr: write /home/codespace/.local/lib/python3.10/site-packages/torch/lib/libtorch_cpu.so: no space left on device
2022-11-29 22:05:55.145Z: 
2022-11-29 22:05:55.173Z: Stop (171320 ms): Run: docker buildx build --load --build-context dev_containers_feature_content_source=/tmp/devcontainercli-root/container-features/0.23.2-1669759381510 --build-arg _DEV_CONTAINERS_BASE_IMAGE=mcr.microsoft.com/devcontainers/universal:linux --build-arg _DEV_CONTAINERS_IMAGE_USER=root --build-arg _DEV_CONTAINERS_FEATURE_CONTENT_SOURCE=dev_container_feature_content_temp --target dev_containers_target_stage -t vsc-features-1fd731dbdc54187530bf301a0589adb6-features -f /tmp/devcontainercli-root/container-features/0.23.2-1669759381510/Dockerfile.extended /var/lib/docker/codespacemount/.persistedshare/empty-folder
2022-11-29 22:05:55.173Z: Error: Command failed: docker buildx build --load --build-context dev_containers_feature_content_source=/tmp/devcontainercli-root/container-features/0.23.2-1669759381510 --build-arg _DEV_CONTAINERS_BASE_IMAGE=mcr.microsoft.com/devcontainers/universal:linux --build-arg _DEV_CONTAINERS_IMAGE_USER=root --build-arg _DEV_CONTAINERS_FEATURE_CONTENT_SOURCE=dev_container_feature_content_temp --target dev_containers_target_stage -t vsc-features-1fd731dbdc54187530bf301a0589adb6-features -f /tmp/devcontainercli-root/container-features/0.23.2-1669759381510/Dockerfile.extended /var/lib/docker/codespacemount/.persistedshare/empty-folder
2022-11-29 22:05:55.173Z:     at loe (/usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js:1887:1339)
2022-11-29 22:05:55.173Z:     at eT (/usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js:1887:1275)
2022-11-29 22:05:55.173Z:     at processTicksAndRejections (internal/process/task_queues.js:95:5)
2022-11-29 22:05:55.174Z:     at async voe (/usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js:1893:2049)
2022-11-29 22:05:55.174Z:     at async Xf (/usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js:1893:3212)
2022-11-29 22:05:55.174Z:     at async Jae (/usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js:2013:15058)
2022-11-29 22:05:55.174Z:     at async Wae (/usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js:2013:14812)
2022-11-29 22:05:55.217Z: Stop (174414 ms): Run: /usr/bin/node /usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js up --user-data-folder /var/lib/docker/codespacemount/.persistedshare --container-data-folder .vscode-remote/data/Machine --container-system-data-folder /var/vscode-remote --workspace-folder /var/lib/docker/codespacemount/workspace/features --id-label Type=codespaces --log-level info --log-format json --config /var/lib/docker/codespacemount/workspace/features/.devcontainer/devcontainer.json --override-config /root/.codespaces/shared/merged_devcontainer.json --default-user-env-probe loginInteractiveShell --mount type=bind,source=/.codespaces/agent/mount/cache,target=/vscode --skip-post-create --update-remote-user-uid-default never --mount-workspace-git-root false
2022-11-29 22:05:55.217Z: Exit code 1

====================================== ERROR ====================================
2022-11-29 22:05:55.246Z: Failed to create container.
=================================================================================
2022-11-29 22:05:55.255Z: Error: Command failed: /usr/bin/node /usr/lib/node_modules/@microsoft/vscode-dev-containers-cli/dist/spec-node/devContainersSpecCLI.js up --user-data-folder /var/lib/docker/codespacemount/.persistedshare --container-data-folder .vscode-remote/data/Machine --container-system-data-folder /var/vscode-remote --workspace-folder /var/lib/docker/codespacemount/workspace/features --id-label Type=codespaces --log-level info --log-format json --config /var/lib/docker/codespacemount/workspace/features/.devcontainer/devcontainer.json --override-config /root/.codespaces/shared/merged_devcontainer.json --default-user-env-probe loginInteractiveShell --mount type=bind,source=/.codespaces/agent/mount/cache,target=/vscode --skip-post-create --update-remote-user-uid-default never --mount-workspace-git-root false
2022-11-29 22:05:55.267Z: Error Code: 1302

====================================== ERROR ====================================
2022-11-29 22:05:55.300Z: Container creation failed.
=================================================================================

So yeah... I don't think this is a huge problem since I was able to get my own copy (my jcbhmr/devcontainers-contrib-features fork) working just fine. I don't know why it borked when I tried to create one on the main devcontainers-contrib/features proper though.

Pipx library script

Should support package injection
Should install pipx if not exists
Should install python if not exists

broken links

Document links set in some Features seem to be broken.

Narrow in scope to use more "ecosystem" features and less "package" features

Opened in response to the discussion in #171. This is an issue tracking implementation progress.


After some consideration and discussion in #171, I think the scope of this repo should be severely restricted. Sure, lots of other features can be added like Haskell, Heroku's CLI, etc. should all be included... But I don't think we need a jest package if we add a "packages" field of some kind to a generic Node.js feature. This is my opinion.

TL;DR: Make generic ecosystems like Haskell, Python, Node.js, etc. accept arbitrary package installers instead of splintering them into their own features.

{
  "image": "mcr.microsoft.com/devcontainers/universal:linux",
  "features": {
    "ghcr.io/devcontainers-contrib/features/python:1": {
      "packages": ["bikeshed~=3.1.0", "pylint==2.10.0"]
    },
    "ghcr.io/devcontainers-contrib/features/node:1": {
      "packages": {
        "typescript": "^4.8.0",
        "prettier": "latest"
      }
    }
  }
}

See advantages/disadvantages in #171

"Official" statements regarding the goal/scope of container features

Just to clarify, Dockerfiles are still fully supported. It's just more an an advanced use case, and we don't want people to have to be Docker experts in order to start using Devcontainers. We believe that devcontainer features make it easier for people to add and maintain functionality in their configuration and encourage the use of features as a starting point. But if you have a scenario that needs more flexibility/control, you can certainly add a Dockerfile.
-- devcontainers/templates#77 (comment)

Recently, we have modified the "Add devcontainer configuration files" command to make it more simpler and easier to understand. We have updated the Templates and built the dev container config using Features (which avoids the need of Dockerfile in most cases).
-- devcontainers/templates#77 (comment)

FWIW - I would not recommend going to the trouble for basic things that you can do in a Dockerfile like doing apt-get install. RUN apt-get update && apt-get -y install is about as simple as it can get. Features are primarily focused on reusable chunks of config and code that Dockerfiles alone cannot provide.
-- devcontainers/templates#77 (comment)

Tasks

  • Start a jcbhmr/devcontainers-contrib-features-172 repo
  • Research whether or not objects can be passed to the options of a feature
  • Add support to the Node.js feature for a "packages" option of some kind
  • Add support to the Python feature for a "packages" option
  • Demonstrate real-world implications of this change
  • Add documentation describing why this is better/worse and alternatives
  • Draw a distinction in user guides between when to use Features and when to use Dockerfiles

Add an organization level readme

Moved to #81

Original

This doesn't actually deal with the features repo, but the entire org itself

Similar to the actual devcontainers organization, I think it might be wise to add a little touch of customization to the organization home page.

Side-by-side comparison:

devcontainers devcontainers-contrib

Suggestions:

  • Add a devcontainers-contrib/devcontainers-contrib repo with a README.md that might even be as simple as my profile's readme
  • Add a custom profile image
    • Maybe the devcontainer logo copy-pasted same as vercel-community
    • Maybe the devcontainer logo with a big stamp of something over the top of it to signify "community"

Pulumi feature fails to install with bash completion

Using a simple configuration, Pulumi fails to install with its default parameters:

{
    "name": "devcontainer",
    "image": "mcr.microsoft.com/devcontainers/base:bullseye",
    "features": {
        "ghcr.io/devcontainers-contrib/features/pulumi:1": {}
    }
}

From the container log, the relevant part seems to be the "Permission denied" errors for creating a symbolic link and for bash completion.

#0 11.20 === Pulumi is now installed! ๐Ÿน ===
#0 11.20 + Please restart your shell or add /home/vscode/.pulumi/bin to your $PATH
#0 11.20 + Get started with Pulumi: https://www.pulumi.com/docs/quickstart
#0 11.20 ln: failed to create symbolic link '/usr/local/bin/pulumi': Permission denied
#0 11.21 /bin/bash: line 7: /etc/bash_completion.d/pulumi: Permission denied
#0 11.21 ERROR: Feature "Pulumi" (ghcr.io/devcontainers-contrib/features/pulumi) failed to install! Look at the documentation at https://github.com/devcontainers-contrib/features/tree/main/src/pulumi for help troubleshooting this error.

Setting `"BASHCOMPLETION":false' like so:

"ghcr.io/devcontainers-contrib/features/pulumi:1": {"BASHCOMPLETION":false}

allows the container to be successfully built.

Add goals for this project to wiki

It would probably be beneficial to add a Goals.md page to the Wiki which outlines the current scope and covered use-cases for this feature collection.

With recent discussion about "what is the scope of features in this repo?" and "what should be a feature?", I think it would be a good idea to consolidate these into a single document. This shouldn't necessarily happen now given that discussion is still ongoing, but it would be foolish to think that we all (@DaneWeber @danielbraun89 and @jcbhmr being primary discuss-ers) remember the gist of like 100+ comments over 10+ threads about goals and scope of this project.

Relevant discussions: #171 #173 #175 #172

Tasks

  • Add a Goals.md to the wiki/ folder
  • Answer "what is the goal of this repo?"
  • Answer "what qualifies as a feature?"
  • Link to relevant discussions for more details

Should this file be called something else? Maybe folded into the wiki/README.md file?

/assign @jcbhmr

angular-cli feature breaks in conjunction with node feature

Hello,

When:

  • using both angular-cli and node features
  • if setting version of the node feature

The angular-cli script will run first and run its own nvm install script. Then, the node feature will run and update the default alias of node. This makes the installed angular-cli inaccessible in the container (by default).

Related/same issue: the angular-cli overlooks nvm installed node regardless of whether a the node feature was used for installation. Presumably because it's not using an interactive shell to check for node.

pulumi cli available only for root

Using a very basic config:

{
    "name": "devcontainer",
    "image": "mcr.microsoft.com/devcontainers/base:bullseye",
    "features": {
        "ghcr.io/devcontainers-contrib/features/pulumi:1": {}
    }
}

pulumi cli will be only available for the root user, not the default UID=1000 user that is logged in by default.

Better contributor docs

This is related to #69 and #75 , but tackles the improvement of developer guides instead of user guides.

Does a Wiki make sense for developer-focused docs? I actively wish ๐Ÿ‘โœ… or ๐Ÿ‘Žโ›” opinions to see if something else would be better/wanted.

Tasks

  • Add an actual guide/walkthrough to create a new feature somewhere (GitHub Wiki or CONTRIBUTING.md)
  • Create a Wiki based on my docs philosophy (see below) with all the nitty gritty guides to add/modify stuff and patterns to follow
    • Detail why we need a check_package function
    • Describe why the repo is structured the way it is (src and test)
    • Explain what that magical source dev-container-features-test-lib does
    • Explain why these features are all grouped in one repo instead of separate repos
    • Explain what exec $SHELL does
  • Trim some of the auto-generated fat off of the CONTRIBUTING.md? ๐ŸŸจ Is this a good idea?
My personal documentation philosophy

๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด This is NOT a guide! This is my own opinion! This is how I structure my own docs. You don't have to adopt this. ๐Ÿ”ด๐Ÿ”ด๐Ÿ”ด

I find that it helps to segment your documentation based on your audience. This means that:

  • A little bit of everything goes in the README.md (it's where everyone goes). If it's small enough, you can only use a README.
  • Guides on how to format code for PR, how to open issues, etc. go in CONTRIBUTING.md. It's for GitHub-related stuff and "what you need to do to contribute" like:
    • Code styles
    • How to pick out good beginner issues
    • Any special PR guidelines like "Ping @ if you change $X"
    • How to go about contributing back
    • Pointers to parts of the Wiki for dev-specific docs
  • Developer docs like... (below) go in the GitHub Wiki. Why? It's not Google-indexed so it doesn't confuse actual "I want to install this" users, and it still acts like a sort-of website.
    • How to install dependencies
    • What dependencies are needed to build the binary
    • What the different make or npm or whatever commands/scripts do
    • How to add new features
    • How it's laid out
    • Why certain tooling/deps are used. Why use pyautogui over pywinauto? In the Wiki.
    • A brief explainer of architecture (Answer "What services does it use?" with something like "It uses Vercel on the backend with React on the frontend and has a Python-powered REST API for ...")
  • User docs go on GitHub Pages or some other legitimate Google-indexable website. This allows Google searches to actually function. Examples on how to use things also go here. Think something like Docusaurus. Think JavaDoc & usage guide. Think like TypeScript's website.

Of course, not all projects have these "segments" of documentation; some don't have a need for developer docs, some don't need user docs, some don't need a website, etc.

โš ๏ธ This is just how I @jcbhmr do things/think of things. It is not necessarily right or what should be done with this repo.

โ„น About the wiki: I always try to keep the Wiki Markdown docs in source control, then sync them to the GitHub public wiki tab on pushes to main via a GitHub Action. This lets PRs affect the docs instead of there only being one copy. Here's a GitHub Action that does this.

If we do make a Wiki for explanations, I recommend that it be tied to a wiki/ folder auto-synced on each push to the actual "published" Wiki tab on GitHub. Sure you could just link to the wiki/Your-title-here.md files like https://github.com/user/repo/tree/main/blob/wiki/Your-title-here.md, but I think it's nicer with the Wiki's auto-generated sidebar, Table of Contents, etc. It's more "website"-looking. Here's a GitHub Action that does this

Styleguide?

I notice that some PRs are reformatting things. I think we should run a code formatted over everything in one big PR to prevent additional superfluous commits in other PRs. Should this be done?

Also, should this repo have a styleguide? Is it large enough to warrant that? If so what format? Anything goes? Use Prettier? Use Prettier shell-formatter plugin?

Tasks

  • Prettier/format all files
  • Add a style guide instruction/notice in CONTRIBUTING.md
  • Add a GitHub Action to auto format new PRs or just main or something else

Feel free to "Close as not planned" if this isn't important.

Fix GitHub Actions warnings

There are a lot of these:

image

TODO: Add suggestions to fix here @jcbhmr

Here's what causes these warnings and how to solve them:

That's it! There are so many errors with the same message since the same action is being run in a matrix (and thus the same actions/checkout@v2 is triggering warnings a lot).

Change repo description to reflect new readme

I humbly suggest that one of the admins with the power to do change the repository's "Description" field from "Contributions are Welcomed!" to "๐Ÿณ Extra add-in features for Devcontainers and GitHub Codespaces". This description field is sort of the "title" for Google search results. I think it would be wise to make it a more substantive description.

image

I personally try to keep the repo-level Description field the same as the tag-line-ish thing that I always put under the <h1> in the readme.

Example from one of my repos

image
image
image

Originally posted by @jcbhmr in #69 (comment)

Restructure Cookiecutter into simpler per-"type" scripts?

My honest opinion on the whole Cookiecutter thing:

It's too complicated. There is too much logic concentrated in a template file that belongs in separate scripting files. Cookiecutter and Yeoman (and any project generator really) are great tools, but I don't think they fit the bill the best here.

They work but it's unwieldy to edit them. The files are too big for what they should be. There should be a separate npm-devcontainer-feature.json and one for pip-devcontainer-feature.json if you keep Cookiecutter IMO. They also spread the logic too far apart. You need to reference variables that you declare in JSON and use in Jinja. You need to declare functions separately. You need dependency management. It's a mess.

An alternative is to split each "type" (NPM, pip, apt) into its own Cookiecutter package, but I think a better option is to ditch Cookiecutter as too overkill for simple file generation.

Take Angular for instance. They use ng generate <type> as a way to create new components, interfaces, app shells, and more. I think this approach of script-based generation should be adopted going forward instead of more complex unweidly (and frankly very intimidating) Cookiecutter template logic. I mean have you seen that devcontainer-feature.json file? It is write-once and never touch again code at its finest.

Another argument is that we really need freaking examples of how to do this? Is it really that complicated to just fill out a form in your terminal basically?

Here's an example to really nail home what I am talking about. This is a complete Feature generator script that works! I just wrote it so it might not have proper error handling. It generates an NPM-based feature.

Try it out on Replit! It actually works! https://replit.com/@jcbhmr/SquigglyRepulsiveSolaris#index.js

#!/usr/bin/env -S deno run -A
const npmName = prompt("What is the name of the NPM package?");
const featName = prompt("What should the feature name be?");
const featId = prompt("What should the feature ID be?");
const featDesc = prompt("What should the feature description be?");
const featTestCmd = prompt("What should the test command be?");

const featObject = {
  name: featName,
  description: featDesc,
  id: featId,
  version: "1.0.0",
  documentationURL: `https://github.com/devcontainers-contrib/features/tree/main/src/${featId}#readme`,
  installAfter: ["ghcr.io/devcontainers/features/node:1"],
  options: {
    version: {
      type: "boolean",
      proposals: ["latest"],
      default: "latest",
      description: `Select the version of ${npmName}`,
    },
  },
};
const featJSON = JSON.stringify(featObject, 0, 4);

const featInstallSH = `#!/usr/bin/env bash
set -Eeuo pipefail

if ! command -v npm &>/dev/null; then
  echo "WARN: 'npm' was not found. Installing Node.js + NPM using devcontainer/features src/node/install.sh..."
  curl -fsSL https://raw.githubusercontent.com/devcontainers/features/main/src/node/install.sh | /bin/bash
fi

npm i -g ${npmName}@\${VERSION:-"latest"}
`;

const featTestSH = `#!/usr/bin/env bash
set -Eeuo pipefail

${featTestCmd}
`;

console.log(`src/${featId}/devcontainer-feature.json`);
console.log(featJSON);
console.log(`src/${featId}/install.sh`);
console.log(featInstallSH);
console.log(`test/${featId}/test.sh`);
console.log(featTestSH);

await Deno.mkdir(`src/${featId}`, { recursive: true }); // Same as 'mkdir -p <folder>'.
await Deno.writeTextFile(`src/${featId}/devcontainer-feature.json`, featJSON);
await Deno.writeTextFile(`src/${featId}/install.sh`, featInstallSH);
await Deno.chmod(`src/${featId}/install.sh`, 0o755); // Default of 'chmod +x <file>' is 755.
await Deno.mkdir(`test/${featId}`, { recursive: true });
await Deno.writeTextFile(`test/${featId}/test.sh`, featTestSH);

image

Then the user experience is so much better! You just run the script and it does it for you. You can even "infer" things from the current Git repo like the remote origin URL for documentation URL generation! And it makes it easier to add new features without coupling them to other features (ie. not as many if-statements). I know you can probably do that in Cookiecutter too, but this is one file instead of like 5 files in 3 directories. It's easier to reason about, follow, and maintain. Especially when compared to that monster of an install.sh template.

For instance, here are some generator script ideas:

  • scripts/generate-new-feature-pip.js
  • scripts/generate-new-feature-apt.py
  • scripts/generate-new-feature-deno.sh
  • scripts/generate-new-feature-brew.rb
  • scripts/generate-new-feature-${yourPackageManager}.${yourFavoriteScriptingLanguage}

Heck, you could even commit a C++ file that compiled and ran itself if you really wanted to!

TL;DR: I want a ๐Ÿ‘โœ… or a ๐Ÿ‘Žโ›” before I invest more time. If I do all the work and the PR doesn't merge, that's not fun for me ๐Ÿ˜ญ.


PS: Yes, you can use Python if you're into Python over TypeScript/JavaScript. I personally like the ability of JavaScript + Deno to be self-contained in a single file even if it includes library stuff using HTTP import URLs.

// Using the Prettier code formatter which is relatively large. It's one URL import away!
// https://github.com/denolib/prettier#readme
import { prettier, prettierPlugins } from "https://denolib.com/denolib/prettier/prettier.ts";

const json = JSON.stringify({ my: "object" })
const opts = { parser: "json", plugins: prettierPlugins };
prettier.format(json, opts);
//=> '{ "my": "object" }\n'

Originally posted by @jcbhmr in #69 (comment)

Turn on GitHub Wiki feature

While the wiki/ folder is designed to work as standalone in-source documentation, the links (like the ones in the readme) assume that there is a https://github.com/devcontainers-contrib/features/wiki. This requires turning on the GitHub Wiki in the Settings tab. It will auto-publish using a GitHub Action.

https://github.com/devcontainers-contrib/features/actions/workflows/Publish%20the%20dev%20wiki.yml

on:
  push:
    branches: [main]
    paths: [wiki/**, .github/workflows/Publish the dev wiki.yml]
# ...

@danielbraun89 is the only one with access to do this (I think)

Github action to auto generate features from feature specs

on push to main - all features will be regenerated and a new PR with new features will be opened
(new features will be tested in the PR test workflow)

in case no changes were detected (generated features are identical to current features) then the PR should not be opened

More robust testing

Any suggestions anyone to help catch these earlier? Something in the test/ folder maybe? More robust shell testing?

I haven't looked into what's required, but I'd think supporting the following would Pretty Darn Good:

  • Run the tests as a non-root user (the REMOTE_USER such as vscode)
  • Provide a .devcontainer.json for each test suite. In particular, I'd like to run tests with defaults and another with specified values.
  • Besides looking for the check commands to run without error, it would be cool to run regex patterns against the output for higher-fidelity but resilient tests.

Some of these installs download a ton of data, so it might be important to cache the downloads somehow.

Originally posted by @DaneWeber in #137 (comment)

I think at a higher level, in terms of devcontainer fixtures, it would make sense to have an integration/smoke test (that runs on everything, not something that every feature has to maintain separately), which actually creates a devcontainer with the feature. I'm not entirely sure how to do that programmatically.

It might be sufficient to have a test that pulls a basic docker image, or even the base devcontainer image, and then checks out the feature and runs install.sh inside of it. That probably would have been enough to catch this. I can give that a try soon, and see if it's as easy as I'm claiming. ๐Ÿ˜†

Originally posted by @fred-asimov in #137 (comment)

There has been a recurring issue where things get merged, all tests pass, and then something like "it literally fails to install because it uses the wrong user account" crops up.

To move foward, I think more testing or at least better testing should be considered. DaneWeber and fred-asimov bring up good ideas (quoted above) that should be considered.

This is not time sensitive and should probably stay open a while. It should be in the back of your mind when making changes

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.