I've been looking into switching over to containers but don't think it's worth it now. So, I'm going to close this issue but have my reasoning here for future reference.
The core issue is that CircuitPython's source tree mixes dependencies into the source tree using submodules. We do this to fix our versions of the deps in the relevant place of the tree. When containers mount the active source to work on into the container, they shadow everything in that part of the filesystem. This makes it difficult to mix cached deps and live source in the same file structure. You can do it with symlinks but then these break the non-container setup. I tried doing it for Zephyr as well but it also has the issue with the directories that west initializes.
I was hoping that initializing a container would be faster than our use of gihub actions cache but it doesn't appear so. The Zephyr action I got going with containers still took three minutes to start the container: https://github.com/tannewt/circuitpython/actions/runs/22928835708/job/66827975607
Lastly, containers add another level of maintenance with an additional prerequisite job that has to build all of the new layers based on dependencies and version them somehow. Our existing use of actions cache is more flexible than this.
This isn't to say we shouldn't have a devcontainer setup to ease getting started for those who want it. It can do all of these steps in an automated way for those who want that. Perhaps we should add a CI job to verify it still works.
I've been looking into switching over to containers but don't think it's worth it now. So, I'm going to close this issue but have my reasoning here for future reference.
The core issue is that CircuitPython's source tree mixes dependencies into the source tree using submodules. We do this to fix our versions of the deps in the relevant place of the tree. When containers mount the active source to work on into the container, they shadow everything in that part of the filesystem. This makes it difficult to mix cached deps and live source in the same file structure. You can do it with symlinks but then these break the non-container setup. I tried doing it for Zephyr as well but it also has the issue with the directories that west initializes.
I was hoping that initializing a container would be faster than our use of gihub actions cache but it doesn't appear so. The Zephyr action I got going with containers still took three minutes to start the container: https://github.com/tannewt/circuitpython/actions/runs/22928835708/job/66827975607
Lastly, containers add another level of maintenance with an additional prerequisite job that has to build all of the new layers based on dependencies and version them somehow. Our existing use of actions cache is more flexible than this.
This isn't to say we shouldn't have a devcontainer setup to ease getting started for those who want it. It can do all of these steps in an automated way for those who want that. Perhaps we should add a CI job to verify it still works.