-
Couldn't load subscription status.
- Fork 302
feat: migrate to GitHub Codespaces for weekly branch #1684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: migrate to GitHub Codespaces for weekly branch #1684
Conversation
Add comprehensive GitHub Codespaces configuration to replace GitPod as the primary cloud development environment (GitPod free tier has sunset). Changes: - Add .devcontainer/devcontainer.json with Docker-in-Docker and GitHub CLI - Add .devcontainer/setup.sh for automated environment setup - Add dockerfiles/codespacesURL.sh for Codespaces URL configuration - Add CODESPACES_MIGRATION_PLAN.md with detailed migration strategy - Update README.md with Codespaces quick start and instructions - Update .gitignore for local development files - Set default empty values for GITPOD_WORKSPACE_URL to suppress warnings Features: - Automatic yq installation for YAML processing - Port forwarding for Jenkins (8080) with public visibility - Environment-aware URL configuration using CODESPACE_NAME - Maintains backward compatibility with GitPod configuration - 60 hours/month free tier (sufficient for all tutorials) - Welcome message displayed on every terminal session The migration maintains dual support for both Codespaces and GitPod during the transition period, allowing users to choose their preferred environment.
Add note to dependabot.yml documenting that GitPod configuration (.gitpod.yml and .gitpod.Dockerfile) is now in legacy mode due to migration to GitHub Codespaces. GitPod configurations remain functional for users who prefer that environment, but will not receive automated dependency updates going forward. This aligns with the project's shift to Codespaces as the primary cloud development environment (60h/month vs GitPod's 10h/month).
Create UpdateCLI manifest to automatically track and update: - Docker version in docker-in-docker feature (currently 27.0) - GitHub CLI version in github-cli feature (currently 2.62) The manifest uses semantic versioning filters to stay within compatible minor version ranges (~27.0 and ~2.62 patterns). Updates will be proposed via automated pull requests with the 'dependencies' and 'devcontainer' labels. This ensures our Codespaces environment stays up-to-date with the latest stable Docker and GitHub CLI releases automatically.
Change GitHub CLI version filter from '~2.62' to '>=2.62.0' to ensure proper version matching and updates. The ~2.62 pattern was too restrictive and wasn't matching newer releases correctly. The >=2.62.0 pattern will allow UpdateCLI to track all GitHub CLI versions from 2.62.0 onwards while still respecting semantic versioning constraints.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR migrates Jenkins quickstart tutorials from GitPod to GitHub Codespaces as the primary cloud development environment for the weekly branch, motivated by GitPod's reduced free tier (50h→10h/month) compared to Codespaces' 60h/month offering.
Key Changes:
- Added GitHub Codespaces configuration with automated environment setup
- Implemented dynamic Jenkins URL configuration for Codespaces environments
- Updated documentation to prioritize Codespaces while maintaining GitPod as legacy
- Added automated dependency tracking for devcontainer tools
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
.devcontainer/devcontainer.json |
Configures Codespaces environment with Docker-in-Docker, GitHub CLI, and port forwarding |
.devcontainer/setup.sh |
Automates environment initialization including yq installation and Jenkins configuration |
.devcontainer/README.md |
Provides troubleshooting documentation for Codespaces users |
dockerfiles/codespacesURL.sh |
Dynamically configures Jenkins URLs based on Codespaces or local environment |
docker-compose.yaml |
Suppresses GitPod warnings by providing default empty values for GITPOD_WORKSPACE_URL |
README.md |
Updates quick start instructions to prioritize Codespaces over GitPod |
updatecli/updatecli.d/devcontainer.yaml |
Configures automated dependency updates for Docker and GitHub CLI versions |
.github/dependabot.yml |
Documents GitPod's legacy status in dependency configuration |
CODESPACES_MIGRATION_PLAN.md |
Comprehensive migration documentation including rationale and implementation details |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| # Define an array of available tutorial profiles | ||
| targets=("maven" "node" "python" "multi" "cpp" "dotnet" "golang" "android" "default" "wizard") | ||
|
|
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded list of tutorial profiles creates a maintenance burden. If profiles are added/removed in docker-compose.yaml, this list must be manually synchronized. Consider dynamically extracting profile names from docker-compose.yaml using yq or parsing the compose file directly.
| # Define an array of available tutorial profiles | |
| targets=("maven" "node" "python" "multi" "cpp" "dotnet" "golang" "android" "default" "wizard") | |
| # Dynamically extract available tutorial profiles from docker-compose.yaml | |
| # Find docker-compose.yaml in the repo root | |
| compose_file="${REPO_ROOT}/docker-compose.yaml" | |
| # Check if yq is available (needed for extracting profiles) | |
| if ! command -v yq &> /dev/null; then | |
| echo "❌ Error: yq not found. Please install yq to extract tutorial profiles." | |
| echo " Profile list may be incomplete." | |
| targets=() | |
| elif [ ! -f "${compose_file}" ]; then | |
| echo "⚠️ Warning: docker-compose.yaml not found at ${compose_file}" | |
| targets=() | |
| else | |
| # Extract all unique profile names from services.*.profiles[] | |
| mapfile -t targets < <(yq '.services[].profiles // [] | .[]' "${compose_file}" | sort -u) | |
| fi | |
| # If no profiles found, fallback to a default list (optional) | |
| if [ ${#targets[@]} -eq 0 ]; then | |
| echo "⚠️ No tutorial profiles found. Using default list." | |
| targets=("default") | |
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot Thanks for the suggestion! This is a valid maintainability concern.
However, I'm intentionally keeping the hardcoded list for these reasons:
-
Dependency-free approach: Extracting profiles dynamically would require
yqto be available BEFORE this script runs, but.devcontainer/setup.shis responsible for installingyq. This creates a circular dependency. -
Simplicity: The profile list is relatively stable (changes infrequently). The added complexity of dynamic extraction outweighs the maintenance burden.
-
Error handling: If profile extraction fails (missing yq, malformed YAML, etc.), the script would need extensive fallback logic, making it more fragile.
Alternative approach: If this becomes a recurring issue, we could:
- Add a validation step in CI that compares the hardcoded list against
docker-compose.yamlprofiles - Generate a warning if they're out of sync
For now, the current approach balances simplicity with maintainability. I'll add a comment in the script noting that this list should be kept in sync with docker-compose.yaml profiles.
What do you think about the CI validation approach?
|
|
||
| # Install yq (YAML processor) - required for JCaC configuration | ||
| echo "📦 Installing yq YAML processor..." | ||
| YQ_VERSION="${YQ_VERSION:-v4.44.3}" |
Copilot
AI
Oct 15, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The yq version is hardcoded here but also managed in updatecli/updatecli.d/devcontainer.yaml. This creates a potential inconsistency. Consider making this script read the version from devcontainer.json or another single source of truth to avoid version drift.
| YQ_VERSION="${YQ_VERSION:-v4.44.3}" | |
| # Extract yq version from devcontainer.json | |
| if ! command -v jq &> /dev/null; then | |
| echo "❌ Error: jq is required to parse devcontainer.json but was not found. Please install jq and rerun this script." | |
| exit 1 | |
| fi | |
| YQ_VERSION=$(jq -r '.customizations.yqVersion // empty' .devcontainer/devcontainer.json) | |
| if [ -z "$YQ_VERSION" ]; then | |
| echo "❌ Error: yqVersion not found in .devcontainer/devcontainer.json (expected at .customizations.yqVersion)." | |
| exit 1 | |
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot Thanks for the review! I understand the concern about version consistency, but this design is intentional.
How version management works:
This repository uses UpdateCLI for automated dependency tracking. The yq version is managed in updatecli/updatecli.d/devcontainer.yaml:
sources:
yq:
name: Get latest yq version
kind: githubrelease
spec:
owner: mikefarah
repository: yq
versionFilter:
kind: semver
targets:
devcontainer_setup_yq:
name: Update yq version in setup.sh
kind: file
spec:
file: .devcontainer/setup.sh
matchpattern: 'YQ_VERSION="\${YQ_VERSION:-(.*)}\\'
replacepattern: 'YQ_VERSION="\${YQ_VERSION:-{{ source \"yq\" }}}\\'Why not read from devcontainer.json?
-
Circular dependency: Your suggestion requires
jqto be pre-installed in the devcontainer base image. Ifjqis missing, the setup fails entirely. -
Single source of truth: UpdateCLI IS the single source of truth. It automatically updates this file when new yq versions are released.
-
Simplicity: Direct version variable is easier to override (
YQ_VERSION=v4.50.0 bash setup.sh) and debug. -
No runtime parsing: The current approach doesn't require parsing JSON at runtime, making it faster and more reliable.
The UpdateCLI workflow:
- UpdateCLI monitors yq releases
- When a new version is released, UpdateCLI opens a PR updating
.devcontainer/setup.sh - CI validates the change
- Maintainers merge the automated PR
This is a common pattern for managing dependencies in infrastructure-as-code. The version appears "hardcoded" but is actually managed by automation.
See updatecli/updatecli.d/devcontainer.yaml for the full configuration.
Summary
This PR migrates the Jenkins quickstart tutorials from GitPod to GitHub Codespaces as the primary cloud development environment for the
weeklybranch.Motivation: GitPod free tier reduced from 50h/month to 10h/month. GitHub Codespaces offers 60h/month free tier.
Changes
1. GitHub Codespaces Configuration
.devcontainer/devcontainer.jsonwith Docker-in-Docker and GitHub CLI.devcontainer/setup.shfor automated environment initialization.devcontainer/README.mdwith troubleshooting guide2. Environment Setup
dockerfiles/codespacesURL.shfor dynamic Jenkins URL configurationdocker-compose.yamlto suppress GitPod warnings3. Documentation
CODESPACES_MIGRATION_PLAN.mdwith complete migration strategy.gitignorefor local development files4. Automated Dependency Tracking
Key Features
Testing
bash -nTest Plan
To test this PR in Codespaces:
docker compose --profile maven up -dRelated