name: Set up Launchable description: >- Install the required dependencies and execute the necessary Launchable commands for test recording inputs: os: required: true description: The operating system that CI runs on. This value is used in Launchable flavor. test-opts: default: none required: false description: >- Test options that determine how tests are run. This value is used in the Launchable flavor. launchable-token: required: false description: >- Launchable token is needed if you want to run Launchable on your forked repository. See https://github.com/ruby/ruby/wiki/CI-Servers#launchable-ci for details. builddir: required: false default: ${{ github.workspace }} description: >- Directory to create Launchable report file. srcdir: required: false default: ${{ github.workspace }} description: >- Directory to (re-)checkout source codes. Launchable retrieves the commit information from the directory. test-task: required: false default: ${{ matrix.test_task }} description: >- Specifies a single test task to be executed. This value is used in the Launchable flavor. Either 'test-task' or 'multi-test-tasks' must be configured. test-tasks: required: false default: '[]' description: >- Specifies an array of multiple test tasks to be executed. For example: '["test", "test-all"]'. If you want to run a single test task, use the 'test-task' input instead. is-yjit: required: false default: 'false' description: >- Whether this workflow is executed on YJIT. outputs: stdout_report_path: value: ${{ steps.global.outputs.stdout_report_path }} description: >- Report file path for standard output. stderr_report_path: value: ${{ steps.global.outputs.stderr_report_path }} description: >- Report file path for standard error. runs: using: composite steps: - name: Enable Launchable conditionally id: enable-launchable run: echo "enable-launchable=true" >> $GITHUB_OUTPUT shell: bash if: >- ${{ (github.repository == 'ruby/ruby' || (github.repository != 'ruby/ruby' && env.LAUNCHABLE_TOKEN)) && (inputs.test-task == 'check' || inputs.test-task == 'test-all' || inputs.test-task == 'test' || contains(fromJSON(inputs.test-tasks), 'test-all') || contains(fromJSON(inputs.test-tasks), 'test')) }} # Launchable CLI requires Python and Java. # https://www.launchableinc.com/docs/resources/cli-reference/ - name: Set up Python uses: actions/setup-python@871daa956ca9ea99f3c3e30acb424b7960676734 # v5.0.0 with: python-version: "3.x" if: >- ${{ steps.enable-launchable.outputs.enable-launchable && !endsWith(inputs.os, 'ppc64le') && !endsWith(inputs.os, 's390x') }} - name: Set up Java uses: actions/setup-java@7a445ee88d4e23b52c33fdc7601e40278616c7f8 # v4.0.0 with: distribution: 'temurin' java-version: '17' if: >- ${{ steps.enable-launchable.outputs.enable-launchable && !endsWith(inputs.os, 'ppc64le') && !endsWith(inputs.os, 's390x') }} - name: Set up Java ppc64le uses: actions/setup-java@7a445ee88d4e23b52c33fdc7601e40278616c7f8 # v4.0.0 with: distribution: 'semeru' architecture: 'ppc64le' java-version: '17' if: >- ${{ steps.enable-launchable.outputs.enable-launchable && endsWith(inputs.os, 'ppc64le') }} - name: Set up Java s390x uses: actions/setup-java@7a445ee88d4e23b52c33fdc7601e40278616c7f8 # v4.0.0 with: distribution: 'semeru' architecture: 's390x' java-version: '17' if: >- ${{ steps.enable-launchable.outputs.enable-launchable && endsWith(inputs.os, 's390x') }} - name: Set global vars id: global shell: bash run: | test_all_enabled="${{ inputs.test-task == 'check' || inputs.test-task == 'test-all' || contains(fromJSON(inputs.test-tasks), 'test-all') }}" btest_enabled="${{ inputs.test-task == 'check' || inputs.test-task == 'test' || contains(fromJSON(inputs.test-tasks), 'test') }}" test_spec_enabled="${{ inputs.test-task == 'check' || inputs.test-task == 'test-spec' || contains(fromJSON(inputs.test-tasks), 'test-spec') }}" echo test_all_enabled="${test_all_enabled}" >> $GITHUB_OUTPUT echo btest_enabled="${btest_enabled}" >> $GITHUB_OUTPUT echo test_spec_enabled="${test_spec_enabled}" >> $GITHUB_OUTPUT echo test_all_report_file='launchable_test_all_report.json' >> $GITHUB_OUTPUT echo btest_report_file='launchable_btest_report.json' >> $GITHUB_OUTPUT echo test_spec_report_dir='launchable_test_spec_report' >> $GITHUB_OUTPUT echo stdout_report_path="launchable_stdout.log" >> $GITHUB_OUTPUT echo stderr_report_path="launchable_stderr.log" >> $GITHUB_OUTPUT if: steps.enable-launchable.outputs.enable-launchable - name: Set environment variables for Launchable shell: bash run: | : # GITHUB_PULL_REQUEST_URL are used for commenting test reports in Launchable Github App. : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/link.py#L42 echo "GITHUB_PULL_REQUEST_URL=${{ github.event.pull_request.html_url }}" >> $GITHUB_ENV : # The following envs are necessary in Launchable tokenless authentication. : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/authentication.py#L20 echo "LAUNCHABLE_ORGANIZATION=${{ github.repository_owner }}" >> $GITHUB_ENV echo "LAUNCHABLE_WORKSPACE=${{ github.event.repository.name }}" >> $GITHUB_ENV : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/authentication.py#L71 echo "GITHUB_PR_HEAD_SHA=${{ github.event.pull_request.head.sha || github.sha }}" >> $GITHUB_ENV echo "LAUNCHABLE_TOKEN=${{ inputs.launchable-token }}" >> $GITHUB_ENV : # To prevent a slowdown in CI, disable request retries when the Launchable server is unstable. echo "LAUNCHABLE_SKIP_TIMEOUT_RETRY=1" >> $GITHUB_ENV echo "LAUNCHABLE_COMMIT_TIMEOUT=1" >> $GITHUB_ENV if: steps.enable-launchable.outputs.enable-launchable - name: Set up path shell: bash working-directory: ${{ inputs.srcdir }} # Since updated PATH variable will be available in only subsequent actions, we need to add the path beforehand. # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path run: echo "$(python -msite --user-base)/bin" >> $GITHUB_PATH if: >- ${{ steps.enable-launchable.outputs.enable-launchable && (startsWith(inputs.os, 'macos') || endsWith(inputs.os, 'ppc64le') || endsWith(inputs.os, 's390x')) }} - name: Set up Launchable id: setup-launchable shell: bash working-directory: ${{ inputs.srcdir }} run: | set -x pip install --user launchable : # The build name cannot include a slash, so we replace the string here. github_ref="${{ github.ref }}" github_ref="${github_ref//\//_}" : # With the --name option, we need to configure a unique identifier for this build. : # To avoid setting the same build name as the CI which runs on other branches, we use the branch name here. build_name="${github_ref}_${GITHUB_PR_HEAD_SHA}" test_opts="${{ inputs.test-opts }}" test_opts="${test_opts// /}" test_opts="${test_opts//=/:}" test_all_test_suite='test-all' btest_test_suite='btest' test_spec_test_suite='test-spec' if [ "${{ inputs.is-yjit }}" = "true" ]; then test_all_test_suite="yjit-${test_all_test_suite}" btest_test_suite="yjit-${btest_test_suite}" test_spec_test_suite="yjit-${test_spec_test_suite}" fi # launchable_setup target var -- refers ${target} prefixed variables launchable_setup() { local target=$1 session eval [ "\${${target}_enabled}" = "true" ] || return eval local suite=\${${target}_test_suite} session=$(launchable record session \ --build "${build_name}" \ --observation \ --flavor os="${{ inputs.os }}" \ --flavor test_task="${{ inputs.test-task }}" \ --flavor test_opts="${test_opts}" \ --flavor workflow="${{ github.workflow }}" \ --test-suite ${suite} \ ) echo "${target}_session=${session}" >> $GITHUB_OUTPUT } launchable record build --name "${build_name}" if launchable_setup test_all; then echo "TESTS=${TESTS:+$TESTS }--launchable-test-reports=${test_all_report_file}" >> $GITHUB_ENV fi if launchable_setup btest; then echo "BTESTS=${BTESTS:+$BTESTS }--launchable-test-reports=${btest_report_file}" >> $GITHUB_ENV fi if launchable_setup test_spec; then echo "SPECOPTS=${SPECOPTS:$SPECOPTS }--launchable-test-reports=${test_spec_report_dir}" >> $GITHUB_ENV echo test_spec_enabled=true >> $GITHUB_OUTPUT fi echo launchable_setup_dir=$(pwd) >> $GITHUB_OUTPUT if: steps.enable-launchable.outputs.enable-launchable env: test_all_enabled: ${{ steps.global.outputs.test_all_enabled }} btest_enabled: ${{ steps.global.outputs.btest_enabled }} test_spec_enabled: ${{ steps.global.outputs.test_spec_enabled }} test_all_report_file: ${{ steps.global.outputs.test_all_report_file }} btest_report_file: ${{ steps.global.outputs.btest_report_file }} test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} - name: make test-spec report directory in build directory shell: bash working-directory: ${{ inputs.builddir }} run: mkdir "${test_spec_report_dir}" if: ${{ steps.setup-launchable.outputs.test_spec_enabled == 'true' }} env: test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} - name: Clean up test results in Launchable uses: gacts/run-and-post-run@674528335da98a7afc80915ff2b4b860a0b3553a # v1.4.0 with: shell: bash working-directory: ${{ inputs.builddir }} post: | rm -f "${test_all_report_file}" rm -f "${btest_report_file}" rm -fr "${test_spec_report_dir}" rm -f launchable_stdout.log rm -f launchable_stderr.log if: always() && steps.setup-launchable.outcome == 'success' env: test_all_report_file: ${{ steps.global.outputs.test_all_report_file }} btest_report_file: ${{ steps.global.outputs.btest_report_file }} test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} - name: Record test results in Launchable uses: gacts/run-and-post-run@674528335da98a7afc80915ff2b4b860a0b3553a # v1.4.0 with: shell: bash working-directory: ${{ inputs.builddir }} post: | if [[ "${test_all_enabled}" = "true" ]]; then \ launchable record attachment \ --session "${test_all_session}" \ "${stdout_report_path}" \ "${stderr_report_path}"; \ launchable record tests \ --session "${test_all_session}" \ raw "${test_all_report_file}" || true; \ fi if [[ "${btest_enabled}" = "true" ]]; then \ launchable record attachment \ --session "${btest_session}" \ "${stdout_report_path}" \ "${stderr_report_path}"; \ launchable record tests \ --session "${btest_session}" \ raw "${btest_report_file}" || true; \ fi if [[ "${test_spec_enabled}" = "true" ]]; then \ launchable record attachment \ --session "${test_spec_session}" \ "${stdout_report_path}" \ "${stderr_report_path}"; \ launchable record tests \ --session "${test_spec_session}" \ raw ${test_spec_report_dir}/* || true; \ fi if: ${{ always() && steps.setup-launchable.outcome == 'success' }} env: test_all_report_file: ${{ steps.global.outputs.test_all_report_file }} btest_report_file: ${{ steps.global.outputs.btest_report_file }} test_spec_report_dir: ${{ steps.global.outputs.test_spec_report_dir }} test_all_enabled: ${{ steps.global.outputs.test_all_enabled }} btest_enabled: ${{ steps.global.outputs.btest_enabled }} test_spec_enabled: ${{ steps.global.outputs.test_spec_enabled }} test_all_session: ${{ steps.setup-launchable.outputs.test_all_session }} btest_session: ${{ steps.setup-launchable.outputs.btest_session }} test_spec_session: ${{ steps.setup-launchable.outputs.test_spec_session }} stdout_report_path: ${{ steps.global.outputs.stdout_report_path }} stderr_report_path: ${{ steps.global.outputs.stderr_report_path }} LAUNCHABLE_SETUP_DIR: ${{ steps.setup-launchable.outputs.launchable_setup_dir }}