Conversation
Generalised spec script to work with both Docker and GH Actions.
Create comprehensive documentation for GitHub Actions improvements: - ROADMAP.md: Detailed analysis of current issues and improvement plan - TODO.kanban.md: Kanban-style task tracker for implementation The roadmap outlines critical fixes needed for CI to work properly, short-term modernization improvements, and long-term plans for language-agnostic testing infrastructure to support future Crystal and Go implementations.
…e images This refactor modernizes the Packer configuration to test path_helper across multiple Ruby versions from 2.3.7 (legacy) to 3.2 (current). Changes: - Removed duplicate ph-r270 source definition (was unused) - Removed hardcoded build sources in favor of dynamic block - Updated locals.rubies array with 5 Ruby versions: - Ruby 2.3.7 + Alpine 3.8 (EOL, legacy testing) - Ruby 2.7 + Alpine 3.16 (EOL 2023, last maintained Alpine) - Ruby 3.0 + Alpine 3.16 (maintenance mode) - Ruby 3.1 + Alpine 3.20 (maintained until 2025-03) - Ruby 3.2 + Alpine 3.22 (actively maintained until 2026-03) - Implemented dynamic source generation using for_each - Fixed Alpine version inconsistency (was alpine3.8 in locals but alpine3.11 in build) Benefits: - Single source of truth for Ruby versions (locals.rubies array) - Easy to add/remove Ruby versions - just edit the array - No duplicate code - Correct Alpine versions for each Ruby release - Self-documenting structure with clear comments Alpine versions were selected based on: - Official Docker Hub image availability - Ruby/Alpine compatibility at time of Ruby release - Security maintenance status of Alpine versions
Synchronizes GitHub Actions CI and Docker/Packer to test the same Ruby versions, ensuring consistent coverage across both local and CI testing environments. Ruby versions selected (Option 3 - Smart Middle Ground): - Ruby 2.3.7 + Alpine 3.8 - Legacy support, proves backwards compatibility - Ruby 2.7 + Alpine 3.16 - Last 2.x release, still common in production - Ruby 3.2 + Alpine 3.22 - Stable modern Ruby, widely adopted - Ruby 3.3 + Alpine 3.22 - Latest stable release Changes: - docker.pkr.hcl: Removed Ruby 3.0 and 3.1, added Ruby 3.3 - GitHub Actions: Changed from [2.3.7, 2.7.0, 3.3.x] to [2.3.7, 2.7, 3.2, 3.3] - Added explanatory comments to both files This gives us: ✓ Manageable test matrix (4 versions vs 5-6) ✓ Coverage of legacy, production, and modern Ruby ✓ Consistency between local Docker tests and CI ✓ Focus on versions actually used in the wild
Add environment variable to test job so shell tests will execute instead of skipping due to missing Docker instance indicator.
Change 'return $PASS' to 'exit $PASS' at end of script since this is a script executed directly, not a sourced function. Using return in a non-sourced script causes an error.
Enable manual workflow execution from GitHub Actions UI for testing and debugging purposes.
Cancel in-progress runs when new commits are pushed to the same branch, saving CI resources and avoiding stale results.
Set minimal permissions (contents: read) following the principle of least privilege for better security.
Set 30-minute job timeout and 10-minute timeouts for dependency installation and test execution to prevent hung workflows.
Use cache-apt-pkgs-action to cache alpine-pbuilder package installation, reducing workflow execution time on subsequent runs.
Combine multiple mv and chmod commands into single operations to reduce the number of subprocess invocations.
Set fail-fast: false to allow all matrix jobs to complete even if one fails, providing complete visibility into test results across all Ruby versions.
Change condition from failure() to always() to preserve test output for debugging. Include Ruby version in artifact name to avoid conflicts in matrix builds.
Generate a formatted summary in GITHUB_STEP_SUMMARY showing test pass/fail status and output for each Ruby version in the workflow run UI.
Show formatted failure output in workflow log when tests fail, making it easier to identify issues without downloading artifacts.
Set 7-day retention for test result artifacts to manage storage while keeping results available for debugging recent runs.
Add CI/CD section describing GitHub Actions workflow features, Ruby version matrix, caching, and test summary capabilities.
Document best practices for workflow modifications including local testing with act, security practices, and key files.
Add comprehensive guide comparing Docker-based local testing, act for simulating GitHub Actions, and actual CI behavior with a comparison table of key differences.
Extract test environment setup into reusable composite action for better maintainability and potential reuse across workflows.
Extract test execution, failure display, and summary generation into reusable composite action with configurable Ruby version input.
The workflow referenced /tmp/install.sh but never copied docker/install.sh to that location. Added the missing copy step to the test environment setup.
- Correct file paths for .ashenv and etc-paths (located in docker/assets/) - Add missing move of docker/install.sh to /tmp - Set PATH_HELPER_DOCKER_INSTANCE environment variable for tests - Change 'return' to 'exit' in shell_spec.sh (scripts should use exit)
- Remove invalid alpine-pbuilder package (doesn't exist on Ubuntu) - Install bc for performance timing calculations - Fix file paths: copy files to /root instead of using install.sh - Run tests from /root where files are located - Fix POSIX compatibility: replace [[ ]] with [ ] and brace expansion - Use ruby from PATH instead of hardcoded /usr/local/bin/ruby - Preserve PATH when running with sudo so ruby is found - Output test_output.log to GITHUB_WORKSPACE for artifact upload
The runner user cannot cd to /root. Wrap commands in sudo bash -c so the cd happens as root.
* Add Crystal CI workflow and language-agnostic composite actions
Implements Phase 3 of ROADMAP.md for multi-language support:
- Created .github/workflows/test-crystal.yml for Crystal implementation testing
* Tests multiple Crystal versions (1.10.1, 1.11.2, 1.14.0, latest)
* Uses modern GitHub Actions (checkout@v4, upload-artifact@v4)
* Includes concurrency control and workflow_dispatch
* Properly sets PATH_HELPER_DOCKER_INSTANCE environment variable
- Created .github/actions/setup-test-env composite action
* Language-agnostic test environment setup
* Installs system dependencies (bc)
* Sets up test directory structure at /root
* Accepts exe-path input for flexibility across implementations
- Created .github/actions/run-shell-tests composite action
* Runs shell_spec.sh tests in standardized way
* Generates test summaries and handles failures
* Works with any language implementation
* Provides detailed test output and GitHub step summaries
These reusable actions support future language implementations (Go, etc.)
while maintaining consistent testing across all implementations.
* Integrate Crystal implementation with CI workflow
Fixes the "Missing shard.yml" error in GitHub Actions by merging the
Crystal implementation files from claude/path-helper-crystal-012YLCVr7zHGNaudpAKEG7HM.
Added files:
- shard.yml: Crystal project configuration with path_helper target
- src/path_helper.cr: Main Crystal entry point
- src/path_helper/*.cr: Core modules (cli, colors, debug, helpers, setup, version)
- .gitignore: Updated with Crystal-specific ignores (/lib/, /.shards/)
The CI workflow can now successfully run:
1. shards install (dependencies)
2. shards build --release (compile Crystal binary to bin/path_helper)
3. Shell tests using the compiled binary
This completes the integration of the Crystal implementation with the
language-agnostic CI infrastructure created in the previous commit.
* Fix Crystal compilation error: undefined method 'default_order'
The error occurred because a variable was defined inside a compile-time
macro block ({% if flag?(:darwin) %}) but accessed in runtime code.
In Crystal, variables defined in compile-time conditionals are not
accessible outside those blocks.
Fixed by:
- Extracting default_order logic into a separate class method
- The method contains the compile-time conditional and returns the
appropriate array based on the platform (darwin vs other)
- Runtime code now calls this method: order = default_order
This allows the compile-time platform detection to work correctly while
making the result accessible to the runtime logic in determine_search_order.
* Remove unsupported timeout-minutes from composite action
GitHub Actions composite actions do not support the 'timeout-minutes'
property on individual steps. This property is only valid at the job
level or for steps in workflow files, not in composite actions.
Fixed by:
- Removed 'timeout-minutes: 10' from the run-tests step
- Timeout is already controlled at the workflow job level (30 minutes)
Error was:
"Unexpected value 'timeout-minutes' at Line: 25, Col: 7"
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Fix invalid character errors in path_helper execution The Ruby script exe/path_helper was being executed directly without explicitly invoking ruby, causing the shell to interpret Ruby bytecode as shell syntax. This resulted in "Invalid char" errors for characters like \x7F, \x02, and \x01. Fixed by explicitly calling 'ruby exe/path_helper' instead of './exe/path_helper' in: - docker/install.sh - spec/shell_spec.sh - .github/workflows/path_helper_tests.yml - .github/actions/run-shell-tests/action.yml * Fix GitHub Actions workflow to reference correct file paths The workflow was trying to move .ashenv and etc-paths from the root directory, but these files are actually located in docker/assets/. Also added the missing step to move docker/install.sh to /tmp/. This fixes the workflow to correctly set up the test environment. --------- Co-authored-by: Claude <noreply@anthropic.com>
* Fix remaining invalid character errors in GitHub Actions The previous PR fixed docker/install.sh and spec/shell_spec.sh but missed two critical locations where path_helper was still being called directly without ruby: 1. .github/workflows/path_helper_tests.yml - Changed to use /tmp/install.sh which properly handles the setup and already has the ruby fix 2. .github/actions/run-shell-tests/action.yml - Changed ./exe/path_helper to ruby exe/path_helper This completes the fix for the invalid character errors that were occurring when the Ruby script was executed as a shell script. * Fix run-shell-tests to execute path_helper directly The run-shell-tests composite action is used by both Ruby and Crystal workflows. When called from the Crystal workflow, /root/exe/path_helper is a compiled Crystal binary, not a Ruby script. Trying to run it with 'ruby exe/path_helper' causes invalid character errors as Ruby tries to parse the binary. Changed to './exe/path_helper' which works for both: - Ruby: Executes via #!/usr/bin/env ruby shebang - Crystal: Executes as native binary Note: docker/install.sh still uses 'ruby exe/path_helper' because in that context it's always the Ruby script, not a Crystal binary. * Fix spec/shell_spec.sh to execute path_helper directly The test script was hardcoding 'ruby exe/path_helper' in 4 locations, which fails when path_helper is a Crystal binary. Changed all calls to execute path_helper directly: - Line 70: test_a_path function - removed 'ruby' prefix - Line 167: setup call - changed to './exe/path_helper' - Lines 219, 226: validation tests - removed 'ruby' prefix This allows the tests to work with both: - Ruby implementation (via #!/usr/bin/env ruby shebang) - Crystal implementation (as native binary) Note: docker/install.sh still uses 'ruby exe/path_helper' as it's only used in Ruby-specific workflows. --------- Co-authored-by: Claude <noreply@anthropic.com>
The shell tests were failing because /etc/paths was created as an empty file during setup, but the tests expected it to contain the standard Unix paths. This caused the path_spec and debug_path_spec tests to fail with EOF errors when comparing expected vs actual output. Fixed in two locations with defensive checks: 1. spec/shell_spec.sh - Copy docker/assets/etc-paths to /etc/paths if empty 2. .github/actions/run-shell-tests/action.yml - Same fix for CI runs The fix only copies the file if: - /etc/paths is empty (doesn't exist or has no content) - docker/assets/etc-paths exists This handles both execution contexts: - Ruby workflow: install.sh already populates /etc/paths via mv - Crystal workflow: run-shell-tests action needs to populate it - Local runs: Works regardless of initial state Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tired of fighting against the tide, Claude puts all PRs to master so that's where we're going,