From 4cb1616bd89ac29a9b445fa2abc5b28f44b609e6 Mon Sep 17 00:00:00 2001 From: Dan McMahill Date: Thu, 21 Apr 2022 22:29:01 -0400 Subject: [PATCH] [ci] Overhaul the ci pipeline and get it all working This has lots of fixes including a more unified flow where differences between platforms is controlled with conditional steps instead of maintaining 2 unique pipelines. On the macOS side, I wasn't able to find xvfb-run so downloaded a copy of the upstream sources from x.org and apply some minor tweaks (`gfmt` instead of `fmt`, more verbose output). There was also an issue when running `make distcheck` on macOS. The desktop icons, currently drawn with tgif, get exported to xpm and on macOS, two of the color names then caused errors when fed to the ImageMagick `convert` utility. This appears to be related to which `rgb.txt` file is found (or not found). Explicitly setting RGBDEF to point at the /opt/X11/... version seems to have taken care of this. --- .github/workflows/ci-pipeline.yml | 165 +++++++++++----- {travis => ci-scripts}/install-pstoedit.sh | 0 {travis => ci-scripts}/install-tgif.sh | 0 ci-scripts/xvfb-run | 217 +++++++++++++++++++++ 4 files changed, 331 insertions(+), 51 deletions(-) rename {travis => ci-scripts}/install-pstoedit.sh (100%) rename {travis => ci-scripts}/install-tgif.sh (100%) create mode 100755 ci-scripts/xvfb-run diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 8282f169..7365ad9d 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -2,90 +2,153 @@ name: Wcalc CI on: push: - branches: [ develop ] + branches: + - develop + - 'dev-*' + - 'ci-*' pull_request: branches: [ develop ] + schedule: + # minute hour day month weekday + - cron: '15 1 1 * *' # Allows you to run this workflow manually from the Actions tab: workflow_dispatch: jobs: - build-ubuntu: - # "ubuntu-latest" == ubuntu-20.04 ('focal'): - runs-on: ubuntu-latest + build: + strategy: + matrix: + # "ubuntu-latest" == ubuntu-20.04 ('focal'): + # windows-latest isn't really supported at this time by wcalc + os: [macos-latest, ubuntu-latest] + runs-on: ${{ matrix.os }} steps: # Checks-out repository under $GITHUB_WORKSPACE: - name: Check out repository code uses: actions/checkout@v3 - - name: apt-get update + + - name: Install Dependencies - macOS + if: runner.os == 'macOS' + run: | + brew update + brew install autoconf + brew install automake + brew install coreutils + brew install gawk + brew install gettext + brew install gtk+ + brew install imagemagick + brew install netpbm + brew install pstoedit + brew install tgif + brew install util-linux + brew install w3m + brew install libxslt + brew install --cask xquartz + brew install xauth + + - name: Homebrew netpbm workaround - macOS + if: runner.os == 'macOS' + run: | + # this ships with netpbm but was giving + # some colors names in the ppmtoxpm output + # that + # convert --colors 16 foo.xpm foo_16.ppm + # didn't like + #RGBDEF="$(brew list netpbm | grep rgb.txt)" + # but this one from XQuartz seems to work + RGBDEF=/opt/X11/share/X11/rgb.txt + echo "Setting: RGBDEF=${RGBDEF}" + echo "RGBDEF=${RGBDEF}" >> $GITHUB_ENV + + - name: apt-get update - Linux + if: runner.os == 'Linux' run: sudo apt-get update - - name: apt-get install + + - name: Install dependencies - Linux + if: runner.os == 'Linux' run: sudo apt-get install -y guile-2.2-dev autoconf automake autopoint + bison + imagemagick libgettextpo-dev libgtk2.0-dev netpbm - # need newer version - #pstoedit w3m + xauth xsltproc - # for tgif + xvfb + + - name: Install tgif dependencies - Linux + if: runner.os == 'Linux' + run: sudo apt-get install -y libxmu-dev xfonts-75dpi gsfonts-x11 - # for pstoedit + + # we need a newer pstoedit + - name: Install pstoedit dependencies - Linux + if: runner.os == 'Linux' + run: sudo apt-get install -y ghostscript - #gcc-8 - #g++-8 + # really should figure out how to cache this: - - name: install pstoedit - run: ./travis/install-pstoedit.sh + - name: Install pstoedit - Linux + if: runner.os == 'Linux' + run: | + ./ci-scripts/install-pstoedit.sh + echo "PSTOEDIT=/usr/bin/pstoedit-3.75" >> $GITHUB_ENV - - name: install tgif - run: ./travis/install-tgif.sh + - name: Install tgif - Linux + if: runner.os == 'Linux' + run: ./ci-scripts/install-tgif.sh - - name: autogen + - name: Autogen run: ./autogen.sh - - name: configure - run: ./configure PSTOEDIT=/usr/bin/pstoedit-3.75 + - name: Post-autogen workarounds + run: | + touch intl/ChangeLog + + - name: Configure + run: ./configure + + - name: Default xvfb-run + run: echo "XVFB_RUN=" >> $GITHUB_ENV + + - name: xvfb-run - Linux + if: runner.os == 'Linux' + run: echo "XVFB_RUN=xvfb-run --auto-servernum" >> $GITHUB_ENV - - name: build - run: make + - name: xvfb-run - macOS + if: runner.os == 'macOS' + run: | + echo "XVFB_RUN=ci-scripts/xvfb-run --auto-servernum --error-file xvfb-run-errors.log" >> $GITHUB_ENV + echo "PATH=/opt/X11/bin:/usr/local/opt/util-linux/bin:${PATH}" >> $GITHUB_ENV - - name: distcheck - run: make distcheck + # Xvfb really wants this directory to exist and be owned by root + sudo mkdir -p -m1777 /tmp/.X11-unix -build-macos: - runs-on: macos-latest - steps: - - name: Check out repository code - uses: actions/checkout@v3 - - name: Install Dependencies + - name: Debug run: | - brew update - brew install --cask microsoft-edge - brew install autoconf - brew install automake - brew install autopoint - brew install libgettextpo-dev - brew install libgtk2.0-dev - brew install netpbm - brew install pstoedit - brew install tgif - brew install w3m - brew install xsltproc - - name: autogen - run: ./autogen.sh - - - name: configure - run: ./configure - - - name: build - run: make + bison --version + convert --version + ls -l $(which tgif) + + - name: Build + run: | + echo "Running: $XVFB_RUN make" + $XVFB_RUN make + + - name: Test stdio-wcalc + run: cd stdio-wcalc && ./run_tests.sh --show-diffs + + - name: Distcheck + run: | + echo "Running: $XVFB_RUN make distcheck" + $XVFB_RUN make distcheck - - name: distcheck - run: make distcheck diff --git a/travis/install-pstoedit.sh b/ci-scripts/install-pstoedit.sh similarity index 100% rename from travis/install-pstoedit.sh rename to ci-scripts/install-pstoedit.sh diff --git a/travis/install-tgif.sh b/ci-scripts/install-tgif.sh similarity index 100% rename from travis/install-tgif.sh rename to ci-scripts/install-tgif.sh diff --git a/ci-scripts/xvfb-run b/ci-scripts/xvfb-run new file mode 100755 index 00000000..590dcb9b --- /dev/null +++ b/ci-scripts/xvfb-run @@ -0,0 +1,217 @@ +#!/bin/sh + +# downloaded from +# https://sources.debian.org/data/main/x/xorg-server/2%3A21.1.3-2/debian/local/xvfb-run +# with very minor changes added here to get this working on macOS with +# some homebrew packages installed + +# This script starts an instance of Xvfb, the "fake" X server, runs a command +# with that server available, and kills the X server when done. The return +# value of the command becomes the return value of this script. +# +# If anyone is using this to build a Debian package, make sure the package +# Build-Depends on xvfb and xauth. + +set -e + +PROGNAME=xvfb-run +SERVERNUM=99 +AUTHFILE= +ERRORFILE=/dev/null +XVFBARGS="-screen 0 1280x1024x24" +LISTENTCP="-nolisten tcp" +XAUTHPROTO=. + +# Query the terminal to establish a default number of columns to use for +# displaying messages to the user. This is used only as a fallback in the event +# the COLUMNS variable is not set. ($COLUMNS can react to SIGWINCH while the +# script is running, and this cannot, only being calculated once.) +DEFCOLUMNS=$(stty size 2>/dev/null | awk '{print $2}') || true +case "$DEFCOLUMNS" in + *[!0-9]*|'') DEFCOLUMNS=80 ;; +esac + +# Display a message, wrapping lines at the terminal width. +message () { + echo "$PROGNAME: $*" | gfmt -t -w ${COLUMNS:-$DEFCOLUMNS} +} + +# Display an error message. +error () { + message "error: $*" >&2 +} + +# Display a usage message. +usage () { + if [ -n "$*" ]; then + message "usage error: $*" + fi + cat <>"$ERRORFILE" 2>&1 + fi + if [ -n "$XVFB_RUN_TMPDIR" ]; then + if ! rm -r "$XVFB_RUN_TMPDIR"; then + error "problem while cleaning up temporary directory" + exit 5 + fi + fi + if [ -n "$XVFBPID" ]; then + kill "$XVFBPID" >>"$ERRORFILE" 2>&1 + fi +} + +# Parse the command line. +ARGS=$(getopt --options +ae:f:hn:lp:s:w: \ + --long auto-servernum,error-file:,auth-file:,help,server-num:,listen-tcp,xauth-protocol:,server-args:,wait: \ + --name "$PROGNAME" -- "$@") +GETOPT_STATUS=$? + +if [ $GETOPT_STATUS -ne 0 ]; then + error "internal error; getopt exited with status $GETOPT_STATUS" + exit 6 +fi + +eval set -- "$ARGS" + +while :; do + case "$1" in + -a|--auto-servernum) SERVERNUM=$(find_free_servernum); AUTONUM="yes" ;; + -e|--error-file) ERRORFILE="$2"; shift ;; + -f|--auth-file) AUTHFILE="$2"; shift ;; + -h|--help) SHOWHELP="yes" ;; + -n|--server-num) SERVERNUM="$2"; shift ;; + -l|--listen-tcp) LISTENTCP="" ;; + -p|--xauth-protocol) XAUTHPROTO="$2"; shift ;; + -s|--server-args) XVFBARGS="$2"; shift ;; + -w|--wait) shift ;; + --) shift; break ;; + *) error "internal error; getopt permitted \"$1\" unexpectedly" + exit 6 + ;; + esac + shift +done + +if [ "$SHOWHELP" ]; then + usage + exit 0 +fi + +if [ -z "$*" ]; then + usage "need a command to run" >&2 + exit 2 +fi + +if ! command -v xauth >/dev/null; then + error "xauth command not found" + exit 3 +fi + +# tidy up after ourselves +trap clean_up EXIT + +# If the user did not specify an X authorization file to use, set up a temporary +# directory to house one. +if [ -z "$AUTHFILE" ]; then + XVFB_RUN_TMPDIR="$(mktemp -d -t $PROGNAME.XXXXXX)" + AUTHFILE="$XVFB_RUN_TMPDIR/Xauthority" + # Create empty file to avoid xauth warning + touch "$AUTHFILE" +fi + +# Start Xvfb. +MCOOKIE=$(mcookie) +tries=10 +while [ $tries -gt 0 ]; do + tries=$(( $tries - 1 )) + message "Tries = ${tries}" >> "$ERRORFILE" + message "AUTOFILE=$AUTHFILE, MCOOKIE=$MCOOKIE, SERVERNUM=$SERVERNUM" >> "$ERRORFILE" + message "XAUTHPROTO=$XAUTHPROTO ERRORFILE=$ERRORFILE" >> "$ERRORFILE" + XAUTHORITY=$AUTHFILE xauth source - << EOF >>"$ERRORFILE" 2>&1 +add :$SERVERNUM $XAUTHPROTO $MCOOKIE +EOF + # handle SIGUSR1 so Xvfb knows to send a signal when it's ready to accept + # connections + trap : USR1 + (trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) & + XVFBPID=$! + + message "XVFBPID = $XVFBPID" >> "$ERRORFILE" + + wait || : + if kill -0 $XVFBPID 2>/dev/null; then + break + elif [ -n "$AUTONUM" ]; then + # The display is in use so try another one (if '-a' was specified). + SERVERNUM=$((SERVERNUM + 1)) + SERVERNUM=$(find_free_servernum) + continue + fi + error "Xvfb failed to start" >&2 + cat $ERRORFILE >& 2 + XVFBPID= + exit 1 +done + +# Start the command and save its exit status. +set +e +message "Running DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE $@" | tee -a "$ERRORFILE" +DISPLAY=:$SERVERNUM XAUTHORITY=$AUTHFILE "$@" +RETVAL=$? +message "$@ returned $RETVAL" | tee -a "$ERRORFILE" +set -e + +if [ $RETVAL -ne 0 ] ; then + error "Command failed with return code $RETVAL" + error "ERRORFILE:" + cat "$ERRORFILE" >&2 +fi + +# Return the executed command's exit status. +if [ -f "$ERRORFILE" ] ; then + message "error log:" + cat "$ERRORFILE" + message "end of error log" +fi + +message "Exiting with $RETVAL" +exit $RETVAL + +# vim:set ai et sts=4 sw=4 tw=80: