|
| 1 | +#!/bin/sh |
| 2 | + |
| 3 | +# travisify.sh |
| 4 | +# |
| 5 | +# Script for enabling or updating Travis CI builds for a given repository. |
| 6 | + |
| 7 | +#set -e |
| 8 | + |
| 9 | +dir="$(dirname "$0")" |
| 10 | + |
| 11 | +travisDir=.travis |
| 12 | +travisConfig=.travis.yml |
| 13 | +travisBuildScript=$travisDir/build.sh |
| 14 | +travisSettingsFile=$travisDir/settings.xml |
| 15 | +credentialsDir=$HOME/.scijava/credentials |
| 16 | +varsFile=$credentialsDir/vars |
| 17 | +signingKeySourceFile=$credentialsDir/scijava-ci-signing.asc |
| 18 | +signingKeyDestFile=$travisDir/signingkey.asc |
| 19 | +pomMinVersion='17.1.1' |
| 20 | +tmpFile=travisify.tmp |
| 21 | + |
| 22 | +info() { echo "- $@"; } |
| 23 | +warn() { echo "[WARNING] $@" 1>&2; } |
| 24 | +err() { echo "[ERROR] $@" 1>&2; } |
| 25 | +die() { err "$@"; exit 1; } |
| 26 | + |
| 27 | +check() { |
| 28 | + for tool in $@ |
| 29 | + do |
| 30 | + which "$tool" >/dev/null || |
| 31 | + die "The '$tool' utility is required but not found" |
| 32 | + done |
| 33 | +} |
| 34 | + |
| 35 | +var() { |
| 36 | + grep "^$1=" "$varsFile" || |
| 37 | + die "$1 not found in $varsFile" |
| 38 | +} |
| 39 | + |
| 40 | +update() { |
| 41 | + file=$1 |
| 42 | + msg=$2 |
| 43 | + test "$msg" || msg="Travis: update $file" |
| 44 | + if [ -e "$file" ] |
| 45 | + then |
| 46 | + if diff -q "$file" "$tmpFile" >/dev/null |
| 47 | + then |
| 48 | + info "$file is already OK" |
| 49 | + else |
| 50 | + info "Updating $file" |
| 51 | + $EXEC rm -rf "$file" |
| 52 | + $EXEC mv -f "$tmpFile" "$file" |
| 53 | + fi |
| 54 | + else |
| 55 | + info "Creating $file" |
| 56 | + $EXEC mkdir -p "$(dirname "$file")" |
| 57 | + $EXEC mv "$tmpFile" "$file" |
| 58 | + f
8000
i |
| 59 | + rm -rf "$tmpFile" |
| 60 | + $EXEC git add "$file" |
| 61 | + $EXEC git diff-index --quiet HEAD -- || $EXEC git commit -m "$msg" |
| 62 | +} |
| 63 | + |
| 64 | +process() { |
| 65 | + cd "$1" |
| 66 | + |
| 67 | + # -- Git sanity checks -- |
| 68 | + repoSlug=$(git remote -v | grep origin | head -n1 | sed 's/.*github.com.\([^ ]*\) .*/\1/') |
| 69 | + test "$repoSlug" && info "Repository = $repoSlug" || die 'Could not determine GitHub repository slug' |
| 70 | + git fetch >/dev/null |
| 71 | + git diff-index --quiet HEAD -- || die "Dirty working copy" |
| 72 | + branch=$(git rev-parse --abbrev-ref HEAD) |
| 73 | + test "$branch" = "master" || die "Non-master branch: $branch" |
| 74 | + git merge --ff --ff-only 'HEAD@{u}' >/dev/null || |
| 75 | + die "Cannot fast forward (local diverging?)" |
| 76 | +# test "$(git rev-parse HEAD)" = "$(git rev-parse 'HEAD@{u}')" || |
| 77 | +# die "Mismatch with upstream branch (local ahead?)" |
| 78 | + |
| 79 | + # -- POM sanity checks -- |
| 80 | + parent=$(xmllint --xpath "//*[local-name()='project']/*[local-name()='parent']/*[local-name()='artifactId']" pom.xml|sed 's/[^>]*>//'|sed 's/<.*//') |
| 81 | + test "$parent" = "pom-scijava" || |
| 82 | + die "Not pom-scijava parent: $parent" |
| 83 | + |
| 84 | + # -- Travis sanity checks -- |
| 85 | + test -e "$travisDir" -a ! -d "$travisDir" && die "$travisDir is not a directory" |
| 86 | + test -e "$travisConfig" -a ! -f "$travisConfig" && die "$travisConfig is not a regular file" |
| 87 | + test -e "$travisConfig" && warn "$travisConfig already exists" |
| 88 | + test -e "$travisBuildScript" && warn "$travisBuildScript already exists" |
| 89 | + |
| 90 | + # -- Do things -- |
| 91 | + |
| 92 | + # Add/update the Travis configuration file. |
| 93 | + cat >"$tmpFile" <<EOL |
| 94 | +language: java |
| 95 | +jdk: oraclejdk8 |
| 96 | +branches: |
| 97 | + only: |
| 98 | + - master |
| 99 | + - "/.*-[0-9]+\\\\..*/" |
| 100 | +install: true |
| 101 | +script: "$travisBuildScript" |
| 102 | +cache: |
| 103 | + directories: |
| 104 | + - "~/.m2/repository" |
| 105 | +EOL |
| 106 | + update "$travisConfig" |
| 107 | + |
| 108 | + # Add/update the Travis build script. |
| 109 | + cat >"$tmpFile" <<EOL |
| 110 | +#!/bin/sh |
| 111 | +curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/travis-build.sh |
| 112 | +sh travis-build.sh |
| 113 | +EOL |
| 114 | + update "$travisBuildScript" |
| 115 | + |
| 116 | + # Remove obsolete Travis-related files. |
| 117 | + if [ -f "$travisSettingsFile" ] |
| 118 | + then |
| 119 | + info "Removing obsolete $travisSettingsFile (travis-build.sh generates it now)." |
| 120 | + $EXEC git rm -f "$travisSettingsFile" |
| 121 | + $EXEC git ci -m "Travis: remove obsolete $travisSettingsFile" |
| 122 | + fi |
| 123 | + |
| 124 | + # Upgrade version of pom-scijava. |
| 125 | + version=$(xmllint --xpath "//*[local-name()='project']/*[local-name()='parent']/*[local-name()='version']" pom.xml|sed 's/[^>]*>//'|sed 's/<.*//') |
| 126 | + # HACK: Using a lexicographic comparison here is imperfect. |
| 127 | + if [ "$version" \< "$pomMinVersion" ] |
| 128 | + then |
| 129 | + info 'Upgrading pom-scijava version' |
| 130 | + sed "s|^ <version>$version</version>$| <version>$pomMinVersion</version>|" pom.xml >"$tmpFile" |
| 131 | + update pom.xml "POM: update pom-scijava parent to $pomMinVersion" |
| 132 | + else |
| 133 | + info "Version of pom-scijava ($version) is OK" |
| 134 | + fi |
| 135 | + |
| 136 | + releaseProfile=$(grep '<releaseProfiles>' pom.xml 2>/dev/null | sed 's/[^>]*>//' | sed 's/<.*//') |
| 137 | + if [ "$releaseProfile" ] |
| 138 | + then |
| 139 | + if [ "$releaseProfile" != 'deploy-to-imagej' ] |
| 140 | + then |
| 141 | + warn "Unknown release profile: $releaseProfile" |
| 142 | + fi |
| 143 | + else |
| 144 | + info 'Adding <releaseProfiles> property' |
| 145 | + cp pom.xml "$tmpFile" |
| 146 | + perl -0777 -i -pe 's/(\n\t<\/properties>\n)/\n\n\t\t<!-- NB: Deploy releases to the ImageJ Maven repository. -->\n\t\t<releaseProfiles>deploy-to-imagej<\/releaseProfiles>\1/igs' "$tmpFile" |
| 147 | + update pom.xml 'POM: deploy releases to the ImageJ repository' |
| 148 | + fi |
| 149 | + |
| 150 | + # update the README |
| 151 | + if ! grep -q "travis-ci.org/$repoSlug" README.md >/dev/null 2>&1 |
| 152 | + then |
| 153 | + info "Adding Travis badge to README.md" |
| 154 | + echo "[](https://travis-ci.org/$repoSlug)" >"$tmpFile" |
| 155 | + echo >>"$tmpFile" |
| 156 | + test -f README.md && cat README.md >>"$tmpFile" |
| 157 | + update README.md 'Travis: add badge to README.md' |
| 158 | + fi |
| 159 | + |
| 160 | + # encrypt key/value pairs in variables file |
| 161 | + if [ -f "$varsFile" ] |
| 162 | + then |
| 163 | + while read p; do |
| 164 | + test "${p:0:1}" = "#" && continue |
| 165 | + info "Encrypting ${p%%=*}" |
| 166 | + echo yes | $EXEC travis encrypt "$p" --add env.global |
| 167 | + done <"$varsFile" |
| 168 | + $EXEC git commit "$travisConfig" -m "Travis: add encrypted environment variables" |
| 169 | + else |
| 170 | + warn "No $varsFile found. Travis will not have any environment variables set!" |
| 171 | + fi |
| 172 | + |
| 173 | + # encrypt GPG keypair |
| 174 | + if [ -f "$signingKeySourceFile" ] |
| 175 | + then |
| 176 | + info "Encrypting $signingKeyDestFile" |
| 177 | + # NB: We have to copy the file first, so that --add does the right thing. |
| 178 | + $EXEC cp "$signingKeySourceFile" "$signingKeyDestFile" |
| 179 | + $EXEC travis encrypt-file "$signingKeyDestFile" "$signingKeyDestFile.enc" --add |
| 180 | + $EXEC rm -f "$signingKeyDestFile" |
| 181 | + $EXEC git add "$travisConfig" "$signingKeyDestFile.enc" |
| 182 | + $EXEC git commit -m "Travis: add encrypted GPG signing keypair" |
| 183 | + else |
| 184 | + warn "No $signingKeySourceFile found. Travis will not be able to do GPG signing!" |
| 185 | + fi |
| 186 | +} |
| 187 | + |
| 188 | +test -d "$credentialsDir" || |
| 189 | + die "This script requires configuration stored in $credentialsDir,\n" \ |
| 190 | + "including $varsFile for needed environment variables,\n" \ |
| 191 | + "and $signingKeySourceFile for signing of artifacts.\n" \ |
| 192 | + "Please contact a SciJava administrator to receive a copy of this content." |
| 193 | + |
| 194 | +# check prerequisites |
| 195 | +check git sed xmllint travis |
| 196 | + |
| 197 | +# parse arguments |
| 198 | +EXEC=: |
| 199 | +while test $# -gt 0 |
| 200 | +do |
| 201 | + case "$1" in |
| 202 | + -f) EXEC=;; |
| 203 | + --) break;; |
| 204 | + -*) echo "Ignoring unknown option: $1" >&2; break;; |
| 205 | + *) break;; |
| 206 | + esac |
| 207 | + shift |
| 208 | +done |
| 209 | + |
| 210 | +test "$EXEC" && warn "Simulation only. Run with -f flag to go for real." |
| 211 | + |
| 212 | +# process arguments |
| 213 | +if [ $# -gt 0 ] |
| 214 | +then |
| 215 | + for d in $@ |
| 216 | + do ( |
| 217 | + echo "[$d]" |
| 218 | + process "$d" |
| 219 | + ) done |
| 220 | +else |
| 221 | + process . |
| 222 | +fi |
0 commit comments