Skip to content

Conversation

@gounthar
Copy link
Collaborator

Summary

This PR migrates the Jenkins quickstart tutorials from GitPod to GitHub Codespaces as the primary cloud development environment for the weekly branch.

Motivation: GitPod free tier reduced from 50h/month to 10h/month. GitHub Codespaces offers 60h/month free tier.

Changes

1. GitHub Codespaces Configuration

  • ✅ Add .devcontainer/devcontainer.json with Docker-in-Docker and GitHub CLI
  • ✅ Add .devcontainer/setup.sh for automated environment initialization
  • ✅ Add .devcontainer/README.md with troubleshooting guide
  • ✅ Configure port forwarding (8080 for Jenkins, 3000/5000 for apps)

2. Environment Setup

  • ✅ Add dockerfiles/codespacesURL.sh for dynamic Jenkins URL configuration
  • ✅ Update docker-compose.yaml to suppress GitPod warnings
  • ✅ Update README.md with Codespaces quick start

3. Documentation

  • ✅ Add CODESPACES_MIGRATION_PLAN.md with complete migration strategy
  • ✅ Mark GitPod as legacy in README and dependabot configuration
  • ✅ Update .gitignore for local development files

4. Automated Dependency Tracking

  • ✅ Create UpdateCLI manifest for devcontainer dependencies (Docker, GitHub CLI)
  • ✅ Configure automatic version tracking with semantic versioning

Key Features

  • 60 hours/month free tier vs GitPod's 10 hours
  • Native GitHub integration - no separate platform needed
  • Automatic setup - yq installation, URL configuration, welcome message
  • Port forwarding - Jenkins (8080) with public visibility
  • Backward compatibility - GitPod configuration remains functional

Testing

  • UpdateCLI manifest syntax validated
  • Shell scripts validated with bash -n
  • Commits follow conventional commit format
  • All files properly formatted

Test Plan

To test this PR in Codespaces:

  1. Open https://codespaces.new/jenkins-docs/quickstart-tutorials?ref=feature/codespaces-migration-weekly
  2. Wait for environment initialization (~2-3 minutes)
  3. Run: docker compose --profile maven up -d
  4. Access Jenkins at the forwarded 8080 port
  5. Verify Jenkins URL configuration is correct
  6. Test other profiles (python, node, multi, etc.)

Related

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.
@github-actions github-actions bot added the repo label Oct 15, 2025
@gounthar gounthar requested a review from Copilot October 15, 2025 17:24
Copy link

Copilot AI left a 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.

Comment on lines +25 to +27
# Define an array of available tutorial profiles
targets=("maven" "node" "python" "multi" "cpp" "dotnet" "golang" "android" "default" "wizard")

Copy link

Copilot AI Oct 15, 2025

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.

Suggested change
# 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

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

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:

  1. Dependency-free approach: Extracting profiles dynamically would require yq to be available BEFORE this script runs, but .devcontainer/setup.sh is responsible for installing yq. This creates a circular dependency.

  2. Simplicity: The profile list is relatively stable (changes infrequently). The added complexity of dynamic extraction outweighs the maintenance burden.

  3. 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.yaml profiles
  • 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}"
Copy link

Copilot AI Oct 15, 2025

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.

Suggested change
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

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

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?

  1. Circular dependency: Your suggestion requires jq to be pre-installed in the devcontainer base image. If jq is missing, the setup fails entirely.

  2. Single source of truth: UpdateCLI IS the single source of truth. It automatically updates this file when new yq versions are released.

  3. Simplicity: Direct version variable is easier to override (YQ_VERSION=v4.50.0 bash setup.sh) and debug.

  4. No runtime parsing: The current approach doesn't require parsing JSON at runtime, making it faster and more reliable.

The UpdateCLI workflow:

  1. UpdateCLI monitors yq releases
  2. When a new version is released, UpdateCLI opens a PR updating .devcontainer/setup.sh
  3. CI validates the change
  4. 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.

@gounthar gounthar merged commit 27702c3 into jenkins-docs:weekly Oct 15, 2025
3 of 4 checks passed
@gounthar gounthar deleted the feature/codespaces-migration-weekly branch October 15, 2025 17:41
@github-actions github-actions bot mentioned this pull request Oct 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant