diff options
Diffstat (limited to '.github/actions')
-rw-r--r-- | .github/actions/launchable/setup/action.yml | 144 | ||||
-rw-r--r-- | .github/actions/setup/directories/action.yml | 174 | ||||
-rw-r--r-- | .github/actions/setup/macos/action.yml | 28 | ||||
-rw-r--r-- | .github/actions/setup/ubuntu/action.yml | 53 | ||||
-rw-r--r-- | .github/actions/slack/action.yml | 39 |
5 files changed, 438 insertions, 0 deletions
diff --git a/.github/actions/launchable/setup/action.yml b/.github/actions/launchable/setup/action.yml new file mode 100644 index 0000000000..6d50318ded --- /dev/null +++ b/.github/actions/launchable/setup/action.yml @@ -0,0 +1,144 @@ +name: Set up Launchable +description: >- + Install the required dependencies and execute the necessary Launchable commands for test recording + +inputs: + report-path: + default: launchable_reports.json + required: true + description: The file path of the test report for uploading to Launchable + + 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 retrives the commit information + from the directory. + +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)) && + (matrix.test_task == 'check' || matrix.test_task == 'test-all') + }} + + # 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 + + - 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 + + - 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 + if: steps.enable-launchable.outputs.enable-launchable + + - name: Set up Launchable + shell: bash + working-directory: ${{ inputs.srcdir }} + run: | + set -x + PATH=$PATH:$(python -msite --user-base)/bin + echo "PATH=$PATH" >> $GITHUB_ENV + pip install --user launchable + launchable verify || true + : # 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. + : # + : # FIXME: Need to fix `WARNING: Failed to process a change to a file`. + : # https://github.com/launchableinc/cli/issues/786 + launchable record build --name ${github_ref}_${GITHUB_PR_HEAD_SHA} + echo "TESTS=${TESTS} --launchable-test-reports=${{ inputs.report-path }}" >> $GITHUB_ENV + if: steps.enable-launchable.outputs.enable-launchable + + - name: Variables to report Launchable + id: variables + shell: bash + run: | + set -x + : # flavor + test_opts="${{ inputs.test-opts }}" + test_opts="${test_opts// /}" + test_opts="${test_opts//=/:}" + echo test-opts="$test_opts" >> $GITHUB_OUTPUT + : # report-path from srcdir + if [ "${srcdir}" = "${{ github.workspace }}" ]; then + dir= + else + # srcdir must be equal to or under workspace + dir=$(echo ${srcdir:+${srcdir}/} | sed 's:[^/][^/]*/:../:g') + fi + report_path="${dir}${builddir:+${builddir}/}${report_path}" + echo report-path="${report_path}" >> $GITHUB_OUTPUT + if: steps.enable-launchable.outputs.enable-launchable + env: + srcdir: ${{ inputs.srcdir }} + builddir: ${{ inputs.builddir }} + report_path: ${{ inputs.report-path }} + + - name: Record test results in Launchable + uses: gacts/run-and-post-run@674528335da98a7afc80915ff2b4b860a0b3553a # v1.4.0 + with: + shell: bash + working-directory: ${{ inputs.srcdir }} + post: | + : # record + launchable record tests --flavor os=${{ inputs.os }} --flavor test_task=${{ matrix.test_task }} --flavor test_opts=${test_opts} raw ${report_path} + rm -f ${report_path} + if: ${{ always() && steps.enable-launchable.outputs.enable-launchable }} + env: + test_opts: ${{ steps.variables.outputs.test-opts }} + report_path: ${{ steps.variables.outputs.report-path }} diff --git a/.github/actions/setup/directories/action.yml b/.github/actions/setup/directories/action.yml new file mode 100644 index 0000000000..5264e0e969 --- /dev/null +++ b/.github/actions/setup/directories/action.yml @@ -0,0 +1,174 @@ +name: Setup directories etc. +description: >- + Set up the source code and build directories (plus some + environmental tweaks) + +inputs: + srcdir: + required: false + default: ${{ github.workspace }} + description: >- + Directory to (re-)checkout source codes. This will be created + if absent. If there is no `configure` file that is also + generated inside. + + builddir: + required: false + default: ${{ github.workspace }} + description: >- + Where binaries and other generated contents go. This will be + created if absent. + + makeup: + required: false + type: boolean + # Note that `default: false` evaluates to a string constant + # `'false'`, which is a truthy value :sigh: + # https://github.com/actions/runner/issues/2238 + default: '' + description: >- + If set to true, additionally runs `make up`. + + checkout: + required: false + type: boolean + default: true + description: >- + If set to '' (false), skip running actions/checkout. This is useful when + you don't want to overwrite a GitHub token that is already set up. + + dummy-files: + required: false + type: boolean + default: '' + description: >- + If set to true, creates dummy files in build dir. + + fetch-depth: + required: false + default: '1' + description: The depth of commit history fetched from the remote repository + + clean: + required: false + type: boolean + default: '' + description: >- + If set to true, clean build directory. + +outputs: {} # nothing? + +runs: + using: composite + + steps: + # Note that `shell: bash` works on both Windows and Linux, but not + # `shell: sh`. This is because GitHub hosted Windows runners have + # their bash manually installed. + - shell: bash + run: | + mkdir -p ${{ inputs.srcdir }} + mkdir -p ${{ inputs.builddir }} + + # Did you know that actions/checkout works without git(1)? We are + # checking that here. + - id: which + shell: bash + run: | + echo "git=`command -v git`" >> "$GITHUB_OUTPUT" + echo "sudo=`command -v sudo`" >> "$GITHUB_OUTPUT" + echo "autoreconf=`command -v autoreconf`" >> "$GITHUB_OUTPUT" + + - if: steps.which.outputs.git + shell: bash + run: | + git config --global core.autocrlf false + git config --global core.eol lf + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage + + - if: inputs.checkout + uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 + with: + path: ${{ inputs.srcdir }} + fetch-depth: ${{ inputs.fetch-depth }} + + - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 + with: + path: ${{ inputs.srcdir }}/.downloaded-cache + key: downloaded-cache + + - if: steps.which.outputs.autoreconf + shell: bash + working-directory: ${{ inputs.srcdir }} + run: ./autogen.sh + + # This is for MinGW. + - if: runner.os == 'Windows' + shell: bash + run: echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV + + - if: runner.os == 'Linux' + shell: bash + run: echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> "$GITHUB_ENV" + + # macOS' GNU make is so old that they doesn't understand `GNUMAKEFLAGS`. + - if: runner.os == 'macOS' + shell: bash + run: echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> "$GITHUB_ENV" + + - if: inputs.makeup + shell: bash + working-directory: ${{ inputs.srcdir }} + run: | + touch config.status + touch .rbconfig.time + sed -f tool/prereq.status template/Makefile.in > Makefile + sed -f tool/prereq.status template/GNUmakefile.in > GNUmakefile + make up + + # Cleanup, runs even on failure + - if: always() && inputs.makeup + shell: bash + working-directory: ${{ inputs.srcdir }} + run: rm -f config.status Makefile rbconfig.rb .rbconfig.time + + - if: steps.which.outputs.sudo + shell: bash + run: | + sudo chmod -R go-w /usr/share + chmod -v go-w $HOME $HOME/.config || : + sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : + + - if: inputs.dummy-files == 'true' + shell: bash + id: dummy-files + working-directory: ${{ inputs.builddir }} + run: | + : Create dummy files in build dir + set {{a..z},{A..Z},{0..9},foo,bar,test,zzz}.rb + for file; do \ + echo > $file "raise 'do not load $file'"; \ + done + # drop {a..z}.rb if case-insensitive filesystem + grep -F A.rb a.rb > /dev/null && set "${@:27}" + echo clean="cd ${{ inputs.builddir }} && rm $*" >> $GITHUB_OUTPUT + + - if: inputs.clean == 'true' + shell: bash + id: clean + run: | + echo distclean='make -C ${{ inputs.builddir }} distclean' >> $GITHUB_OUTPUT + echo remained-files='find ${{ inputs.builddir }} -ls' >> $GITHUB_OUTPUT + [ "${{ inputs.builddir }}" = "${{ inputs.srcdir }}" ] || + echo final='rmdir ${{ inputs.builddir }}' >> $GITHUB_OUTPUT + + - name: clean + uses: gacts/run-and-post-run@7aec950f3b114c4fcf6012070c3709ecff0eb6f8 # v1.4.0 + with: + working-directory: + post: | + ${{ steps.dummy-files.outputs.clean }} + ${{ steps.clean.outputs.distclean }} + ${{ steps.clean.outputs.remained-files }} + ${{ steps.clean.outputs.final }} diff --git a/.github/actions/setup/macos/action.yml b/.github/actions/setup/macos/action.yml new file mode 100644 index 0000000000..b96e959aa6 --- /dev/null +++ b/.github/actions/setup/macos/action.yml @@ -0,0 +1,28 @@ +name: Setup macOS environment +description: >- + Installs necessary packages via Homebrew. + +inputs: {} # nothing? + +outputs: {} # nothing? + +runs: + using: composite + + steps: + - name: brew + shell: bash + run: | + brew install --quiet gmp libffi openssl@1.1 zlib autoconf automake libtool + + - name: Set ENV + shell: bash + run: | + for lib in gmp; do + ruby_configure_args="${ruby_configure_args:+$ruby_configure_args }--with-${lib%@*}-dir=$(brew --prefix $lib)" + done + for lib in openssl@1.1; do + CONFIGURE_ARGS="${CONFIGURE_ARGS:+$CONFIGURE_ARGS }--with-${lib%@*}-dir=$(brew --prefix $lib)" + done + echo ruby_configure_args="${ruby_configure_args}" >> $GITHUB_ENV + echo CONFIGURE_ARGS="${CONFIGURE_ARGS}" >> $GITHUB_ENV diff --git a/.github/actions/setup/ubuntu/action.yml b/.github/actions/setup/ubuntu/action.yml new file mode 100644 index 0000000000..a9e5b41951 --- /dev/null +++ b/.github/actions/setup/ubuntu/action.yml @@ -0,0 +1,53 @@ +name: Setup ubuntu environment +description: >- + At the beginning there was no way but to copy & paste `apt-get` + everywhere. But now that we have composite actions, it seems better + merge them into one. + +inputs: + arch: + required: false + default: '' + description: >- + Architecture. Because we run this on a GitHub-hosted runner + acceptable value for this input is very limited. + +outputs: + arch: + value: ${{ steps.uname.outputs.uname }} + description: >- + Actual architecture. This could be different from the one + passed to the `inputs.arch`. For instance giving `i386` to this + action yields `i686`. + +runs: + using: composite + + steps: + - name: set SETARCH + shell: bash + run: echo "SETARCH=${setarch}" >> "$GITHUB_ENV" + env: + setarch: ${{ inputs.arch && format('setarch {0} --', inputs.arch) }} + + - id: uname + name: uname + shell: bash + run: | + echo uname=`${SETARCH} uname -m` >> "$GITHUB_OUTPUT" + echo dpkg=`${SETARCH} uname -m | sed s/686/386/` >> "$GITHUB_OUTPUT" + + - name: apt-get + shell: bash + env: + arch: ${{ inputs.arch && format(':{0}', steps.uname.outputs.dpkg) || '' }} + run: | + set -x + ${arch:+sudo dpkg --add-architecture ${arch#:}} + sudo apt-get update -qq || : + sudo apt-get install --no-install-recommends -qq -y -o=Dpkg::Use-Pty=0 \ + ${arch:+cross}build-essential${arch/:/-} \ + libssl-dev${arch} libyaml-dev${arch} libreadline6-dev${arch} \ + zlib1g-dev${arch} libncurses5-dev${arch} libffi-dev${arch} \ + autoconf ruby + sudo apt-get install -qq -y pkg-config${arch} || : diff --git a/.github/actions/slack/action.yml b/.github/actions/slack/action.yml new file mode 100644 index 0000000000..c98be085a8 --- /dev/null +++ b/.github/actions/slack/action.yml @@ -0,0 +1,39 @@ +name: Post a message to slack +description: >- + We have our ruby/action-slack webhook. However its arguments are + bit verbose to be listed in every workflow files. Better merge them + into one. + +inputs: + SLACK_WEBHOOK_URL: + required: true + description: >- + The URL to post the payload. This is an input because it tends + to be stored in a secrets valut and a composite action cannot + look into one. + + label: + required: false + description: >- + Human-readable description of the run, something like "DEBUG=1". + This need not be unique among runs. + +outputs: {} # Nothing? + +runs: + using: composite + + steps: + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 + with: + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }}${{ inputs.label && format(' / {0}', inputs.label) }}", + "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", + "commit": "${{ github.sha }}", + "branch": "${{ github.ref_name }}" + } + env: + SLACK_WEBHOOK_URL: ${{ inputs.SLACK_WEBHOOK_URL }} + if: ${{github.event_name == 'push' && startsWith(github.repository, 'ruby/')}} |