See More

#!/bin/sh # github-actionify.sh # # Script for enabling or updating GitHub Action builds for a given repository. #set -e dir="$(dirname "$0")" ciDir=.github ciSlugBuild=workflows/build.yml ciConfigBuild=$ciDir/$ciSlugBuild ciSetupScript=$ciDir/setup.sh ciBuildScript=$ciDir/build.sh pomMinVersion='17.1.1' tmpFile=github-actionify.tmp msgPrefix="CI: " info() { echo "- $@"; } warn() { echo "[WARNING] $@" 1>&2; } err() { echo "[ERROR] $@" 1>&2; } die() { err "$@"; exit 1; } check() { for tool in $@ do which "$tool" >/dev/null || die "The '$tool' utility is required but not found" done } update() { file=$1 msg=$2 exe=$3 test "$msg" || msg="update $file" if [ -e "$file" ] then if diff -q "$file" "$tmpFile" >/dev/null then info "$file is already OK" else info "Updating $file" $EXEC rm -rf "$file" $EXEC mv -f "$tmpFile" "$file" fi else info "Creating $file" $EXEC mkdir -p "$(dirname "$file")" $EXEC mv "$tmpFile" "$file" fi rm -rf "$tmpFile" $EXEC git add "$file" if [ -n "$exe" ] then info "Adding execute permission to $file" $EXEC git update-index --chmod=+x "$file" fi $EXEC git diff-index --quiet HEAD -- || $EXEC git commit -m "$msgPrefix$msg" } process() { cd "$1" # -- Git sanity checks -- repoSlug=$(grep '' pom.xml | sed 's;.*github.com[/:]\(.*/.*\).*;\1;') test "$repoSlug" && info "Repository = $repoSlug" || die 'Could not determine GitHub repository slug' case "$repoSlug" in *.git) die "GitHub repository slug ('$repoSlug') ends in '.git'; please fix the POM" ;; esac git fetch >/dev/null git diff-index --quiet HEAD -- || die "Dirty working copy" currentBranch=$(git rev-parse --abbrev-ref HEAD) upstreamBranch=$(git rev-parse --abbrev-ref --symbolic-full-name @{u}) remote=${upstreamBranch%/*} defaultBranch=$(git remote show "$remote" | grep "HEAD" | sed 's/.*: //') test "$currentBranch" = "$defaultBranch" || die "Non-default branch: $currentBranch" git merge --ff --ff-only 'HEAD@{u}' >/dev/null || die "Cannot fast forward (local diverging?)" # test "$(git rev-parse HEAD)" = "$(git rev-parse 'HEAD@{u}')" || # die "Mismatch with upstream branch (local ahead?)" # -- POM sanity checks -- parent=$(grep -A4 '' pom.xml | grep '' | sed 's;.*\(.*\).*;\1;') if [ -z "$SKIP_PARENT_CHECK" ] then test "$parent" = "pom-scijava" || die "Not pom-scijava parent: $parent. Run with -p flag to skip this check." fi # Change pom.xml from Travis CI to GitHub Actions domain="github.com" sed 's/Travis CI/GitHub Actions/g' pom.xml | sed "s;travis-ci.*;github.com/$repoSlug/actions;g" >"$tmpFile" update pom.xml "switch from Travis CI to GitHub Actions" # -- GitHub Action sanity checks -- test -e "$ciDir" -a ! -d "$ciDir" && die "$ciDir is not a directory" test -e "$ciConfigBuild" -a ! -f "$ciConfigBuild" && die "$ciConfigBuild is not a regular file" test -e "$ciConfigBuild" && warn "$ciConfigBuild already exists" test -e "$ciBuildScript" && warn "$ciBuildScript already exists" test -e "$ciSetupScript" && warn "$ciSetupScript already exists" # -- GitHub Action steps -- actionCheckout="uses: actions/checkout@v4" actionSetupJava="name: Set up Java uses: actions/setup-java@v4 with: java-version: '8' distribution: 'zulu' cache: 'maven'" actionSetupConda="name: Set up conda uses: s-weigand/setup-conda@v1 - name: Install conda packages run: conda env update -f environment.yml -n base" actionSetupCI="name: Set up CI environment run: $ciSetupScript shell: bash" actionExecuteBuild="name: Execute the build run: $ciBuildScript shell: bash" actionSecrets="env: GPG_KEY_NAME: \${{ secrets.GPG_KEY_NAME }} GPG_PASSPHRASE: \${{ secrets.GPG_PASSPHRASE }} MAVEN_USER: \${{ secrets.MAVEN_USER }} MAVEN_PASS: \${{ secrets.MAVEN_PASS }} CENTRAL_USER: \${{ secrets.CENTRAL_USER }} CENTRAL_PASS: \${{ secrets.CENTRAL_PASS }} SIGNING_ASC: \${{ secrets.SIGNING_ASC }}" # -- Do things -- # Add/update the GitHub Actions build configuration file. cat >"$tmpFile" <>"$tmpFile" cat >>"$tmpFile" <"$tmpFile" <"$tmpFile" <' pom.xml | grep '' | sed 's;.*\(.*\).*;\1;') # HACK: Using a lexicographic comparison here is imperfect. if [ "$version" \< "$pomMinVersion" ] then info 'Upgrading pom-scijava version' sed "s|^ $version$| $pomMinVersion|" pom.xml >"$tmpFile" update pom.xml "update pom-scijava parent to $pomMinVersion" else info "Version of pom-scijava ($version) is OK" fi fi # ensure section is present releaseProfile=$(grep '' pom.xml 2>/dev/null | sed 's/[^>]*>//' | sed 's/<.*//') if [ "$releaseProfile" ] then case "$releaseProfile" in sign,deploy-to-scijava) info 'No changes needed to property' ;; deploy-to-scijava) info 'Updating property' sed 's;\(\).*\(\);\1sign,deploy-to-scijava\2;' pom.xml >"$tmpFile" update pom.xml 'sign JARs when deploying releases' ;; *) warn "Unknown release profile: $releaseProfile" ;; esac else info 'Adding property' cp pom.xml "$tmpFile" perl -0777 -i -pe 's/(\n\t<\/properties>\n)/\n\n\t\t\n\t\tsign,deploy-to-scijava<\/releaseProfiles>\1/igs' "$tmpFile" update pom.xml 'deploy releases to the SciJava repository' fi # update the README # https://docs.github.com/en/actions/managing-workflow-runs/adding-a-workflow-status-badge if grep -q "travis-ci.*svg" README.md >/dev/null 2>&1 then info "Updating README.md GitHub Action badge" sed "s;travis-ci.*;$domain/$repoSlug/actions/$ciSlugBuild/badge.svg)](https://$domain/$repoSlug/actions/$ciSlugBuild);g" README.md >"$tmpFile" update README.md 'update README.md badge link' elif grep -qF "$domain/$repoSlug/actions/$ciSlugBuild/badge.svg" README.md >/dev/null 2>&1 then info "GitHub Action badge already present in README.md" else info "Adding GitHub Action badge to README.md" echo "[![Build Status](https://$domain/$repoSlug/actions/$ciSlugBuild/badge.svg)](https://$domain/$repoSlug/actions/$ciSlugBuild)" >"$tmpFile" echo >>"$tmpFile" test -f README.md && cat README.md >>"$tmpFile" update README.md 'add README.md badge link' fi # remove old Travis CI configuration test ! -e .travis.yml || $EXEC git rm -rf .travis.yml test ! -e .travis || $EXEC git rm -rf .travis $EXEC git diff-index --quiet HEAD -- && info "No old CI configuration to remove." || $EXEC git commit -m "${msgPrefix}remove Travis CI configuration" } cat <&2; break;; *) break;; esac shift done test "$EXEC" && warn "Simulation only. Run with -f flag to go for real." # process arguments if [ $# -gt 0 ] then for d in $@ do ( echo "[$d]" process "$d" ) done else process . fi