Skip to content

Speed up Ubuntu *env setup and add CI#7

Merged
ngs merged 10 commits into
masterfrom
ci/ubuntu-setup-workflow
Jun 14, 2026
Merged

Speed up Ubuntu *env setup and add CI#7
ngs merged 10 commits into
masterfrom
ci/ubuntu-setup-workflow

Conversation

@ngs

@ngs ngs commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

Source-building Ruby/Python made the devcontainer "installing dotfiles" step appear stuck, especially in Codespaces. This PR speeds up the Ubuntu setup, updates the pinned language versions past EOL, and adds GitHub Actions CI that actually runs the setup.

Performance (bf7635b)

  • Run setup.d/ubuntu/*.sh in parallel after 001-apt.sh completes, with per-script logs (/tmp/dotfiles-setup-<ts>/<name>.log); any failure fails the whole setup after all jobs are reaped
  • Export MAKE_OPTS="-j$(nproc)" before each *env install
  • Skip rdoc/ri generation via RUBY_CONFIGURE_OPTS="--disable-install-doc"; build Python with --enable-shared
  • Update pinned versions past EOL: Node 18.16.0 → 24.16.0 (Active LTS "Krypton"), Ruby 3.2.2 → 4.0.5, Python 3.11.3 → 3.14.6, Go 1.19.8 → 1.26.4
  • git pull pyenv/goenv on each run so new version definitions are available

CI (3294dbf)

  • Extract the parallel runner into script/setup-ubuntu.sh so setup.sh and CI share the same code path
  • .github/workflows/ci.yml: lint job (bash -n over all shell scripts) + ubuntu-setup job that runs the setup end-to-end, verifies node/ruby/python/go/gcloud versions, and uploads per-script logs as artifacts
  • Fix 001-apt.sh for Ubuntu 24.04: python3.8-devpython3-dev, and add dev libraries (zlib, ffi, readline, bz2, sqlite3, lzma, ncurses) required to build Ruby/Python from source
  • Fix 004-pyenv.sh: put ~/.pyenv/bin on PATH before eval'ing pyenv init -, whose output invokes the pyenv command itself on recent pyenv

Test plan

  • Ran script/setup-ubuntu.sh inside mcr.microsoft.com/devcontainers/base:ubuntu (arm64) as the vscode user — all 5 scripts succeeded and node v24.16.0 / ruby 4.0.5 / Python 3.14.6 / go1.26.4 verified
  • ubuntu-setup CI job on this PR covers amd64

ngs added 3 commits June 13, 2026 09:33
Building Ruby/Python from source made the devcontainer "installing
dotfiles" step appear stuck, especially in Codespaces.

- Run setup.d/ubuntu scripts in parallel after 001-apt.sh completes,
  writing per-script logs and failing the whole setup if any job fails
- Export MAKE_OPTS="-j$(nproc)" before each *env install
- Skip rdoc/ri generation via RUBY_CONFIGURE_OPTS and build Python
  with --enable-shared
- Pull pyenv/goenv on each run so new version definitions are available
- Update pinned versions past EOL: Node 18.16.0 -> 24.16.0 (LTS),
  Ruby 3.2.2 -> 4.0.5, Python 3.11.3 -> 3.14.6, Go 1.19.8 -> 1.26.4
Extract the parallel setup.d/ubuntu runner from setup.sh into
script/setup-ubuntu.sh so setup.sh and CI share the same code path,
and add a workflow that syntax-checks all shell scripts and runs the
Ubuntu setup end-to-end (apt + parallel *env installs), verifying the
installed versions and uploading per-script logs as artifacts.

Fixes found by running the setup in a devcontainer base image:

- 001-apt.sh: python3.8-dev no longer exists on Ubuntu 24.04; use
  python3-dev and add the dev libraries (zlib, ffi, readline, bz2,
  sqlite3, lzma, ncurses) required to build Ruby and Python from source
- 004-pyenv.sh: put ~/.pyenv/bin on PATH before eval'ing pyenv init,
  whose output invokes the pyenv command itself on recent pyenv

Verified inside mcr.microsoft.com/devcontainers/base:ubuntu (arm64):
Node 24.16.0, Ruby 4.0.5, Python 3.14.6, Go 1.26.4 all install
successfully.
postgresql-all pins the distro's postgresql-common, which conflicts
with the newer PGDG postgresql-common preinstalled on GitHub Actions
runners (and other images with the PGDG apt repo), breaking apt with
unmet dependencies. The plain postgresql metapackage plus libpq-dev
installs cleanly from either repo and covers actual usage.

Copilot AI left a comment

Copy link
Copy Markdown

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 refactors Ubuntu environment setup to be faster and more observable (parallel per-script execution with logs), updates the pinned runtime versions, and adds GitHub Actions CI to run the Ubuntu setup end-to-end.

Changes:

  • Added script/setup-ubuntu.sh to run setup.d/ubuntu/*.sh with 001-apt.sh first, then parallel execution + per-script log files.
  • Updated Ubuntu setup scripts to pull latest *env version definitions and pin newer Node/Ruby/Python/Go versions, with build-speed env vars.
  • Added .github/workflows/ci.yml to lint shell scripts and execute/verify Ubuntu setup in CI.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
setup.sh Switches Ubuntu setup invocation to the shared script/setup-ubuntu.sh entrypoint.
script/setup-ubuntu.sh New parallel runner for Ubuntu setup scripts with per-script logging and aggregated failure handling.
setup.d/ubuntu/001-apt.sh Updates Ubuntu 24.04 apt packages and adds build dependencies for source builds.
setup.d/ubuntu/002-nodenv.sh Updates pinned Node version and adds MAKE_OPTS for faster source builds.
setup.d/ubuntu/003-rbenv.sh Updates pinned Ruby version and configures faster Ruby builds (parallel + no docs).
setup.d/ubuntu/004-pyenv.sh Updates pinned Python version, fixes PATH/init ordering, and configures faster Python builds.
setup.d/ubuntu/005-goenv.sh Updates pinned Go version and refreshes goenv definitions.
.github/workflows/ci.yml Adds CI: shell syntax lint + Ubuntu setup run with version verification and log artifacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread setup.sh Outdated
Comment thread setup.sh Outdated
Comment thread .github/workflows/ci.yml Outdated
claude added 2 commits June 13, 2026 04:13
- setup.sh: Guard $WSL_DISTRO_NAME / $CODESPACES tests with default
  expansion and quoting so unset vars don't abort setup under set -e;
  drop the now-unneeded set +u/-u wrapper and use POSIX '=' in tests
- ci.yml: Pick bash -n vs sh -n per script shebang so sh-only syntax
  errors aren't missed by bash -n
Resolves the Dependabot critical alert (arbitrary file read / RCE via the
Vitest UI/Browser API server, affecting vitest < 3.2.6) in the
turnstile-spin worker template. Also add package-lock.json so Dependabot
can determine installed versions and auto-update going forward.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.

Comment thread .github/workflows/ci.yml Outdated
Comment on lines +48 to +52
node --version
ruby --version
python --version
go version
gcloud --version

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 0eef47d.

The "Verify installed versions" step now asserts that the installed node/ruby/python/go versions match the pinned VERSION= values instead of only printing them. The expected versions are extracted from each setup.d/ubuntu/*.sh script (single source of truth, no drift), and the job now exits non-zero on any mismatch or fallback to system binaries.

View diff

- "Verify installed versions" step now asserts node/ruby/python/go
  match the pinned VERSION= values instead of only printing them
- Expected versions are extracted from each setup.d/ubuntu/*.sh script
  so the check never drifts from the source of truth
- CI now fails on version mismatch or fallback to system binaries

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.

Comment thread setup.d/ubuntu/004-pyenv.sh Outdated
Comment on lines +10 to +11
# 新しいバージョン定義を取得するため更新する
git -C ~/.pyenv pull

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in be4b89d.

The update now runs only when ~/.pyenv/.git exists (so a non-git install via package/manual extraction/symlink no longer aborts setup) and uses git pull --ff-only to avoid creating an unintended merge. The same guard was applied to nodenv/rbenv plugin updates for consistency.

View diff

Comment thread setup.d/ubuntu/005-goenv.sh Outdated
Comment on lines +10 to +11
# 新しいバージョン定義を取得するため更新する
git -C ~/.goenv pull

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in be4b89d.

The update now runs only when ~/.goenv/.git exists and uses git pull --ff-only, so a non-git install no longer breaks setup and no merge commit is ever created.

View diff

Comment thread .github/workflows/ci.yml Outdated
esac
echo "==> $checker $f"
$checker "$f" || status=1
done < <(find setup.sh script/setup-ubuntu.sh setup.d -name '*.sh' -print0)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in be4b89d.

The lint job now enumerates all tracked shell scripts via git ls-files '*.sh' instead of a hardcoded path list, so env.sh and env.d/*.sh (and any future scripts) are covered. Shebang-less sourced fragments like env.sh / env.d/* are classified as bash so their bash/zsh syntax isn't false-flagged by sh -n. Verified all tracked scripts pass locally.

View diff

- *env setup: guard repo updates behind a `.git` check and use
  `git pull --ff-only` so a non-git install (package/manual/symlink)
  no longer aborts setup and updates never create an unintended merge
  (nodenv/rbenv plugin pulls and pyenv/goenv main-repo pulls)
- CI lint: lint all tracked shell scripts via `git ls-files '*.sh'`
  instead of a hardcoded path list, covering env.sh and env.d/*.sh
- CI lint: classify shebang-less sourced fragments (env.sh, env.d/*)
  as bash so their bash/zsh syntax isn't false-flagged by `sh -n`

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

ngs added 3 commits June 15, 2026 01:14
The "Verify installed versions" step relied on `rbenv init -` / `goenv init -`
to put shims on PATH, but those implementations don't prepend shims, so the
runner's system ruby (3.2.3) and go (1.24.13) shadowed the rbenv/goenv globals
and the assert failed. Explicitly prepend the shims dirs to PATH.

Also add AGENTS.md with repo-specific agent guidance (zsh `status` readonly,
shebang-less env.d lint, *env version pinning + shims, GnuPG conf generation
and signing unlock). CLAUDE.md is now a symlink to AGENTS.md.
Prepending shims fixed node/python/go but ruby still resolved to the
runner's system ruby (3.2.3) despite rbenv global 4.0.5 being installed.
Use `<env> exec <tool>` so each *env runs its global-managed binary
directly, independent of PATH/shims ordering. Dump rbenv/goenv selection
on mismatch for debuggability. Also drop a stray `exit $status` left from
the variable rename (st).
…rsion

Diagnostics revealed rbenv resolved `system` from the repo's own
`.ruby-version` (the dotfiles repo intentionally pins itself to system
ruby), shadowing the global 4.0.5 that setup installed. Run each
`*env exec` from $HOME so the repo-local pin no longer applies and the
assert checks the global version setup actually installed.
@ngs ngs merged commit dceb2b0 into master Jun 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants