Org Workspace
Code name:
org-workspace
Clones the repos of a GitHub org next to your project and keeps a VS Code multi-root workspace
file up to date. Add it to one project’s devcontainer.json and the other repos are there when
the container is created.
Use it when several repos of the same org are developed together. For a single repo it does nothing useful.
Also included automatically: repairs broken host paths in your git config and restores your SSH commit-signing key on every attach, on both local and cloud containers, with nothing to set up on your end — see
helpers4-commonfor how it works.
With no options, it takes the org from your project’s origin remote and clones every repo you
can see, except forks and archived ones. Each repo goes to /workspaces/<repo> and a
<org>.code-workspace file is created in your project’s root folder. Open it once with
File > Open Workspace from File…. VS Code cannot open it for you from inside a container.
To pick the repos yourself, or to skip some:
A fixed repos list gives the same result on every rebuild, even when the org adds or removes
repos.
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
org | string | "" | GitHub org (or user) to clone from. Empty means the owner of your origin remote. |
repos | string | "" | Comma-separated repos to clone. When set, autoDiscover is ignored. |
autoDiscover | string | "true" | "true": public and private repos, no forks, no archived. "false": clone nothing. Or a list of categories, e.g. "public,fork": public, private, internal, fork, archived. |
exclude | string | "" | Comma-separated repos to skip, whether they come from repos or autoDiscover. |
generateCodeWorkspace | boolean | true | Create or update the .code-workspace file. |
codeWorkspaceName | string | "" | File name. Empty means <org>.code-workspace. |
What it does
Section titled “What it does”- At build,
install.shinstalls the script and makes/workspaceswritable for your user. - When the container is created, the script:
- clones each repo into a Docker volume (
helpers4-org-workspace-${devcontainerId}, mounted at/mnt/h4org-workspace) and links it from/workspaces/<repo>. The clones live in the volume, so a rebuild keeps your local branches and uncommitted work; - updates the
.code-workspacefile to match what is in/workspaces.
- clones each repo into a Docker volume (
A failed clone, or no access to a repo, prints a warning and the rest carries on. The script always exits 0, because a failing lifecycle command would stop the ones after it.
Your project and mounted folders
Section titled “Your project and mounted folders”Three kinds of folders live in /workspaces, and only one is managed on disk:
| Folder | On disk | In the .code-workspace file |
|---|---|---|
Your project (where devcontainer.json is) | never touched, and its repo is never cloned again, even under another folder name | always listed (.) |
| A link into the volume, made by this feature | created and removed to follow the repo list | listed while it exists |
| Anything else: a folder you mounted, cloned or copied there | never touched, and not cloned over | listed while it is a git checkout |
So a repo you mount yourself at /workspaces/<repo> wins over the clone. It stays even when the
repo leaves the list: you mounted it, you remove it.
The .code-workspace file
Section titled “The .code-workspace file”The entries that point at /workspaces/<name> follow the disk: a git checkout there is added,
and an entry whose folder is gone or excluded is removed. Other entries (outside /workspaces,
uri entries) and your settings are left alone.
Each org repo is named with an icon for its status, the first that applies:
| Icon | Status |
|---|---|
| 📦 | archived |
| 🔀 | fork |
| 🔒 | private |
| 🏢 | internal |
| 🌍 | public |
A name you wrote yourself is kept. Only a missing name, the plain repo name or a name with one of these icons is updated, so the icon follows when a repo changes status. Folders outside the org keep their plain name.
Cleaning up
Section titled “Cleaning up”A repo that is no longer wanted (you excluded it, or it was archived or deleted upstream) loses
its link in /workspaces and its entry in the workspace file. Its clone is deleted only when git
confirms nothing would be lost: no uncommitted or ignored files (except node_modules), no stash,
no commit missing from the remote. Otherwise the clone stays in the volume and a warning says so.
Nothing is unlinked when the list of repos looks incomplete: when gh repo list fails, when it
returns nothing, or when nothing is left once exclude and your project’s repo are taken out.
A repos list is taken as it is: a typo in it (typscript) unlinks the repo you meant, as if you
had removed it.
Limits
Section titled “Limits”- GitHub only, and one org per project.
- The repos are cloned when the container is created. A repo added to the org, or archived, shows up (or goes) after the next rebuild.
- A
.code-workspacefile with comments is left as it is, because it cannot be edited safely. Otherwise the file is rewritten the way VS Code writes it: tabs, no final newline. - Needs an authenticated
gh, whichgithub-devprovides.
Codespaces
Section titled “Codespaces”Should work, since gh is already authenticated there and named volumes behave the same. Not
tested in a real Codespace yet.
OS and Architecture Support
Section titled “OS and Architecture Support”- OS: Linux (Debian/Ubuntu-based images)
- Architectures: amd64, arm64
Version History
Section titled “Version History”- v1.1.0: Folder names get a status icon (public, private, internal, fork, archived). The
workspace file now matches what is in
/workspaces: an archived repo no longer stays in it after a rebuild, and dead entries are removed.autoDiscoverwith two visibilities no longer lets the third one in. Your project’s repo is never cloned again under another folder name. Mounted folders are listed, andgherrors are shown. - v1.0.1:
autoDiscoverdefaults to"true". Newexcludeoption. The script no longer fails the container when something goes wrong, and/workspacesis writable at build time. It now runs when the container is created instead of at every start, and removes repos that are no longer wanted. - v1.0.0: Initial release.
