Skip to content

Commit 57dd0fe

Browse files
authored
Merge pull request #137 from edx/pwnage101/codespaces-support
feat: Initial GitHub Codespaces support
2 parents 4a2f4b0 + d1983c7 commit 57dd0fe

File tree

6 files changed

+260
-1
lines changed

6 files changed

+260
-1
lines changed

.devcontainer/devcontainer.json

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"customizations": {
3+
"vscode": {
4+
"settings": {
5+
"terminal.integrated.profiles.linux": { "zsh": { "path": "/bin/zsh" } },
6+
"terminal.integrated.profiles.osx": { "zsh": { "path": "/bin/zsh" } },
7+
"terminal.integrated.profiles.windows": { "zsh": { "path": "/bin/zsh" } },
8+
"terminal.integrated.defaultProfile.osx": "zsh",
9+
"terminal.integrated.defaultProfile.linux": "zsh",
10+
"terminal.integrated.defaultProfile.windows": "zsh",
11+
"terminal.integrated.scrollback": 10000
12+
}
13+
},
14+
"codespaces": {
15+
"repositories": {
16+
"edx/edx-themes": {
17+
"permissions": "read-all"
18+
}
19+
}
20+
}
21+
},
22+
"features": {
23+
"ghcr.io/devcontainers/features/sshd:1": {
24+
"version": "latest"
25+
},
26+
"ghcr.io/rocker-org/devcontainer-features/apt-packages:1": {
27+
"packages": "ripgrep"
28+
}
29+
},
30+
"containerEnv": {
31+
"DEVSTACK_WORKSPACE": "${containerWorkspaceFolder}/edx-repos"
32+
},
33+
"updateContentCommand": ".devcontainer/updateContentCommand.sh",
34+
"postCreateCommand": ".devcontainer/postCreateCommand.sh",
35+
"postStartCommand": ".devcontainer/postStartCommand.sh",
36+
"forwardPorts": [
37+
1976, 1984, 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
38+
2001, 3001, 3406, 5335, 7474, 8000, 8081, 8734, 8735, 9021, 9201, 9202,
39+
9301, 9600, 18000, 18010, 18040, 18110, 18120, 18130, 18150, 18160,
40+
18170, 18270, 18280, 18381, 18400, 18450, 18734, 18760, 18787, 19001,
41+
27017, 44567
42+
],
43+
"portsAttributes": {
44+
"3406": { "label": "mysql80" },
45+
"27017": { "label": "mongo" },
46+
"9201": { "label": "elasticsearch710" },
47+
"9301": { "label": "elasticsearch710" },
48+
"9202": { "label": "opensearch12" },
49+
"9600": { "label": "opensearch12" },
50+
"8081": { "label": "schema-registry" },
51+
"18000": { "label": "lms" },
52+
"19876": { "label": "lms (JS test debugging)" },
53+
"18010": { "label": "studio" },
54+
"19877": { "label": "studio (JS test debugging)" },
55+
"44567": { "label": "forum" },
56+
"5335": { "label": "prospectus" },
57+
"18381": { "label": "discovery" },
58+
"18130": { "label": "ecommerce" },
59+
"18150": { "label": "credentials" },
60+
"18120": { "label": "edx_notes_api" },
61+
"2000": { "label": "frontend-app-learning" },
62+
"1998": { "label": "frontend-app-payment" },
63+
"18400": { "label": "frontend-app-publisher" },
64+
"1994": { "label": "frontend-app-gradebook" },
65+
"1999": { "label": "frontend-app-authn" },
66+
"18734": { "label": "registrar" },
67+
"1976": { "label": "frontend-app-program-console" },
68+
"3001": { "label": "frontend-app-library-authoring" },
69+
"2001": { "label": "frontend-app-course-authoring" },
70+
"1997": { "label": "frontend-app-account" },
71+
"1995": { "label": "frontend-app-profile" },
72+
"18040": { "label": "xqueue" },
73+
"7474": { "label": "coursegraph" },
74+
"18110": { "label": "insights" },
75+
"19001": { "label": "analyticsapi" },
76+
"1993": { "label": "frontend-app-ora-grading" },
77+
"1984": { "label": "frontend-app-communications" },
78+
"1990": { "label": "frontend-app-learner-record" },
79+
"18450": { "label": "frontend-app-support-tools" },
80+
"1996": { "label": "frontend-app-learner-dashboard" },
81+
"9021": { "label": "kafka" },
82+
"18787": { "label": "program-intent-engagement" },
83+
"1991": { "label": "frontend-app-admin-portal" },
84+
"8734": { "label": "frontend-app-learner-portal-enterprise" },
85+
"8735": { "label": "frontend-app-enterprise-public-catalog" },
86+
"18170": { "label": "license-manager" },
87+
"18160": { "label": "enterprise-catalog" },
88+
"18270": { "label": "enterprise-access" },
89+
"18280": { "label": "enterprise-subsidy" },
90+
"8000": { "label": "paragon-pattern-library" },
91+
"18760": { "label": "ai-translations" }
92+
}
93+
}

.devcontainer/postCreateCommand.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
# postCreateCommand.sh - Finalize container setup after creation.
3+
#
4+
# This script will contribute to the time it takes to launch a new codespace.
5+
6+
# Print each command being executed.
7+
set -x
8+
9+
echo "Invoking $0"
10+
11+
# Overwrite the default welcome message.
12+
# This is displayed the first time you open a newly created Codespace.
13+
VSCODE_DEVCONTAINERS_CONFIG=/usr/local/etc/vscode-dev-containers
14+
if [[ -d "$VSCODE_DEVCONTAINERS_CONFIG" ]]; then
15+
sudo cp .devcontainer/welcome.txt ${VSCODE_DEVCONTAINERS_CONFIG}/first-run-notice.txt
16+
fi
17+
18+
# Prepare git auth so that developers can push branches directly from a
19+
# codespaces shell. This step tells git to use auth setup by the GH CLI.
20+
#
21+
# In order for this to actually work, the developer still needs to log into the
22+
# GH CLI from a Codespace terminal using `gh auth login`. That step is
23+
# interactive and opens a browser, so cannot be part of this script.
24+
gh auth setup-git

.devcontainer/postStartCommand.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env bash
2+
# postStartCommand.sh - Run each time the codespace is successfully started.
3+
#
4+
# This script contributes the time it takes to start the codespace _every day_.
5+
6+
# Print each command being executed.
7+
set -x
8+
9+
echo "Invoking $0"
10+
11+
# `gh auth login` generates SSH keys under the home directory, but that part of
12+
# the filesystem is ephemeral. Make a decent effort to store the keys in a
13+
# persistent mount, and recover the keys if necessary.
14+
if ls -d ~/.ssh/id_*; then
15+
# Backup user-generated ~/.ssh folder if keys are present.
16+
rsync -avh ~/.ssh/ /workspaces/.ssh-backup/
17+
elif [[ -d /workspaces/.ssh-backup ]]; then
18+
# Recover user-generated ~/.ssh folder if absent and a backup exists.
19+
rsync -avh /workspaces/.ssh-backup/ ~/.ssh/
20+
fi
21+
# No action is taken if neither ~/.ssh nor /workspaces/.ssh-backup exists.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env bash
2+
# updateContentCommand.sh - Finalize container setup after creation.
3+
#
4+
# The result of these commands are cached in pre-built codespaces and will
5+
# not contribute to any developer delay. When new codespaces are pre-built
6+
# behind the scenes, this script runs, so it'll probably run weekly.
7+
8+
# Print each command being executed.
9+
set -x
10+
11+
echo "Invoking $0"
12+
13+
# Set zsh as the default shell when SSHing into this codespace (has no impact
14+
# on VS Code terminals).
15+
sudo chsh -s /bin/zsh ${USER}
16+
17+
# Add github.com to ssh known hosts to avoid crashing the build with a prompt.
18+
mkdir -p ~/.ssh
19+
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
20+
21+
# Checkout all edx repos using https because at this point the developer has
22+
# not yet authed via the GH CLI. Later we'll, configure each repo to use ssh.
23+
mkdir -p "$DEVSTACK_WORKSPACE"
24+
mkdir -p "$DEVSTACK_WORKSPACE/src"
25+
SHALLOW_CLONE=1 make dev.clone.https
26+
27+
# Provision the core app databases.
28+
make dev.provision
29+
# Provision the enterprise app databases.
30+
make dev.provision.license-manager+enterprise-catalog+enterprise-access+enterprise-subsidy
31+
32+
# Make sure pyenv & pyenv-virtualenv are installed, updated, and configured
33+
# correctly for zsh shells.
34+
export PYENV_ROOT="/workspaces/.pyenv"
35+
# Idempotently install or update pyenv.
36+
if [[ -d ${PYENV_ROOT}/bin ]]
37+
then (cd ${PYENV_ROOT}; git pull)
38+
else GIT_TERMINAL_PROMPT=0 git clone https://github.com/pyenv/pyenv.git ${PYENV_ROOT}
39+
fi
40+
# Idempotently install or update pyenv-virtualenv.
41+
if [[ -d ${PYENV_ROOT}/plugins/pyenv-virtualenv/bin ]]
42+
then (cd ${PYENV_ROOT}/plugins/pyenv-virtualenv; git pull)
43+
else GIT_TERMINAL_PROMPT=0 git clone https://github.com/pyenv/pyenv-virtualenv.git ${PYENV_ROOT}/plugins/pyenv-virtualenv
44+
fi
45+
# Configure/enable pyenv for zsh.
46+
(
47+
cat <<EOF
48+
export PYENV_ROOT="$PYENV_ROOT"
49+
[[ -d \$PYENV_ROOT/bin ]] && export PATH="\$PYENV_ROOT/bin:\$PATH"
50+
eval "\$(pyenv init - zsh)"
51+
eval "\$(pyenv virtualenv-init - zsh)"
52+
EOF
53+
) > ~/.oh-my-zsh/custom/edx-devstack.zsh
54+
# Enable pyenv for this bash script too.
55+
export PATH="$PYENV_ROOT/bin:$PATH"
56+
eval "$(pyenv init - bash)"
57+
eval "$(pyenv virtualenv-init - bash)"
58+
59+
# Install a decent long-term python version.
60+
PYTHON_VERSION=3.12
61+
pyenv install --skip-existing $PYTHON_VERSION
62+
63+
# Find all repos and loop over them:
64+
repo_dirs=( $(find $DEVSTACK_WORKSPACE -mindepth 1 -maxdepth 3 -type d -name .git) )
65+
repo_dirs=( ${repo_dirs[@]%/.git} )
66+
for repo_dir in ${repo_dirs[@]}; do
67+
pushd $repo_dir
68+
69+
# Produce a human-readable virtualenv name.
70+
virtualenv_name="${repo_dir#$DEVSTACK_WORKSPACE/}"
71+
virtualenv_name="${virtualenv_name//\//_}"
72+
73+
# Set up all repos with virtualenvs.
74+
pyenv virtualenv $PYTHON_VERSION $virtualenv_name
75+
pyenv local $virtualenv_name
76+
77+
# Configure all repo clones to use SSH instead of HTTPS.
78+
sed -i 's/https:\/\/github.com\//[email protected]:/g' .git/config
79+
80+
popd
81+
done

.devcontainer/welcome.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
👋 Welcome to 2U Devstack for Open edX Platform in GitHub Codespaces!
2+
3+
This pre-built codespace has virtualenvs configured, repositories cloned, and
4+
databases provisioned. There's just a few more things for you to do...
5+
6+
Initial Setup
7+
=============
8+
9+
1. Authenticate with github from this new codespace:
10+
11+
GITHUB_TOKEN= gh auth login --hostname github.com --git-protocol ssh
12+
13+
2. Navigate to your new ssh key in GitHub settings and configure SSO support:
14+
15+
https://github.com/settings/keys
16+
17+
3. Connect to this codespace using VS Code with the Github Codespaces extension:
18+
19+
https://marketplace.visualstudio.com/items/?itemName=GitHub.codespaces
20+
21+
Usage
22+
=====
23+
24+
Start your day by connecting to this workspace from VS Code and start up
25+
services from a terminal:
26+
27+
make dev.up
28+
29+
Important directories:
30+
31+
* /workspaces/devstack - This is the main devstack repository.
32+
* /workspaces/devstack/edx-repos/* - Individual edx service repository clones.
33+
34+
More Info
35+
=========
36+
37+
* https://2u-internal.atlassian.net/wiki/spaces/SOL/pages/2003370007/Devstack+on+Codespaces+Guide

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,7 @@ local.mk
107107
options.local.mk
108108

109109
# emacs
110-
*~
110+
*~
111+
112+
# GitHub Codespaces destination path for repo clones
113+
edx-repos/

0 commit comments

Comments
 (0)