Skip to content

Commit d0cea1c

Browse files
committed
feat: update instance workflow
BB-9946
1 parent d768451 commit d0cea1c

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""
2+
Update a Tutor instance config.yml with the built image reference.
3+
4+
Usage:
5+
python update_config_image.py \
6+
--config-file instances/<instance>/config.yml \
7+
--service <openedx|mfe> \
8+
--image-name <repo/name or repo/name:tag> \
9+
--image-tag <tag>
10+
11+
Behavior:
12+
- If image-name already contains a ':', it is used as-is.
13+
- Otherwise, ':<image-tag>' is appended (image-tag must be provided).
14+
- The service name is mapped to the config key to update.
15+
"""
16+
17+
import argparse
18+
from pathlib import Path
19+
20+
import yaml
21+
22+
23+
def merge_dicts(dict1, dict2):
24+
"""Given two dict, merge the second dict into the first.
25+
26+
The dicts can have arbitrary nesting.
27+
"""
28+
for key in dict2:
29+
if isinstance(dict2[key], dict):
30+
if key in dict1 and key in dict2:
31+
merge_dicts(dict1[key], dict2[key])
32+
else:
33+
dict1[key] = dict2[key]
34+
else:
35+
# At scalar types, we iterate and merge the
36+
# current dict that we're on.
37+
dict1[key] = dict2[key]
38+
39+
40+
def parse_args() -> argparse.Namespace:
41+
parser = argparse.ArgumentParser(
42+
description="Update config.yml image reference based on service"
43+
)
44+
parser.add_argument(
45+
"--config-file", required=True, help="Path to instance config.yml"
46+
)
47+
# parser.add_argument(
48+
# "--new-config", required=True, help="Service name, e.g. 'openedx' or 'mfe'"
49+
# )
50+
return parser.parse_args()
51+
52+
53+
def load_yaml(path: Path) -> dict:
54+
if not path.exists():
55+
return {}
56+
57+
with path.open("r", encoding="utf-8") as f:
58+
data = yaml.safe_load(f) or {}
59+
60+
if not isinstance(data, dict):
61+
raise SystemExit("Root of YAML must be a mapping (object)")
62+
63+
return data
64+
65+
66+
def save_yaml(path: Path, data: dict) -> None:
67+
with path.open("w", encoding="utf-8") as f:
68+
yaml.safe_dump(data, f, sort_keys=False)
69+
70+
71+
def main() -> None:
72+
args = parse_args()
73+
config_path = Path(args.config_file)
74+
75+
data = load_yaml(config_path)
76+
merge_dicts(data, {"EDX_PLATFORM_VERSION": "release/ulmo"})
77+
save_yaml(config_path, data)
78+
79+
80+
if __name__ == "__main__":
81+
main()
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Update Instance
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
INSTANCE_NAME:
7+
description: "Instance to build"
8+
required: true
9+
type: string
10+
RUNNER_WORKFLOW_LABEL:
11+
description: 'The label of the runner workflow to run'
12+
required: false
13+
type: string
14+
default: "ubuntu-latest"
15+
secrets:
16+
SSH_PRIVATE_KEY:
17+
description: "Private SSH key for accessing private repositories"
18+
required: true
19+
20+
jobs:
21+
update-instance:
22+
needs:
23+
- generate-env-dir
24+
runs-on: ${{ inputs.RUNNER_WORKFLOW_LABEL }}
25+
concurrency:
26+
group: update-instance-${{ inputs.INSTANCE_NAME }}
27+
cancel-in-progress: false
28+
steps:
29+
- name: Setup Python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: 3.12
33+
cache: 'pip'
34+
35+
- name: Install PyYAML
36+
run: pip install pyyaml
37+
38+
- name: Setup SSH agent
39+
uses: webfactory/ssh-agent@v0.9.0
40+
with:
41+
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
42+
43+
- name: Add GitHub to known hosts
44+
run: ssh-keyscan github.com >> ~/.ssh/known_hosts
45+
46+
- name: Configure git
47+
run: |
48+
git config user.name "GitHub Actions"
49+
git config user.email "actions@github.com"
50+
51+
- name: Checkout repository
52+
uses: actions/checkout@v4
53+
54+
- name: Checkout workflow scripts
55+
uses: actions/checkout@v4
56+
with:
57+
repository: open-craft/phd-cluster-template
58+
ref: main
59+
path: workflow-scripts
60+
61+
- name: Update config.yml with provided configs
62+
env:
63+
CONFIG_FILE: instances/${{ inputs.INSTANCE_NAME }}/config.yml
64+
SCRIPT_PATH: workflow-scripts/.github/workflows/scripts/update_config.py
65+
run: |
66+
# Update config.yml
67+
python "$SCRIPT_PATH" \
68+
--config-file "$CONFIG_FILE"
69+
70+
- name: Commit and push changes
71+
run: |
72+
git add instances/${{ inputs.INSTANCE_NAME }}
73+
74+
if git diff --cached --quiet; then
75+
echo "No changes to commit"
76+
else
77+
git commit -m "chore: update config for ${{ inputs.INSTANCE_NAME }}"
78+
git pull origin ${{ github.ref_name }} --rebase
79+
git push
80+
fi

0 commit comments

Comments
 (0)