Skip to content
Michael Lyle edited this page Jul 17, 2017 · 28 revisions

The process

  • Ensure the AndroidGCS AndroidManifest.xml is bumped to the current version before beginning the checklist.

  • Prepare the tag and push to a release branch (as appropriate, based on what process has been followed on this branch to date.

    git fetch upstream
    git checkout upstream/next
    git checkout -b codename
    git push upstream codename
    git tag -a Release-YYYYDDMM       [date in UTC, give an appropriate descriptive message]
    git push upstream Release-YYYYDDMM

The git tag format used for releases is Release-yyyymmdd, optionally with a suffix .[0-9] to make it clear that a build is fundamentally a hotfix or corrected build.

  • Trigger the build

http://jar.lyle.org:8080/job/dronin/build?delay=0sec

Specify the tag name

  • Write the release notes for the tag on Github
https://github.com/d-ronin/dRonin/releases
  • Download and upload the artifacts (yuck)

  • Use package/release-asset-info.py to tag the artifacts with pretty names. It takes --help. Need a appropriate github token.

  • Confirm artifacts, etc.

  • Instruct Jenkins to preserve the build forever.

  • Update the topic on IRC

  • Close or move remaining bugs into next release, as appropriate.

  • Update the Releases page.

  • Sign and upload the AGCS artifact to the Play store.

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore dronin.keystore androidgcs-neat-unsigned.apk dronin
tools/android-sdk-linux/build-tools/20.0.0/zipalign -v 4 androidgcs-neat-unsigned.apk androidgcs-neat.apk
  • Append the githash to the UAVO_GIT_VERSIONS in the makefile so that future versions of AndroidGCS will work with this release.

  • Stage commits like this: https://github.com/d-ronin/d-ronin.github.io/commit/16db6133c4b7b2ad25017afc403bfe5113b3af70 first on preview builds, then on past release builds.

  • Remove all "possible hotfix" tags from closed issues/PRs, because there is an official release with them.

  • Remove all previous releases that are superseded by hotfixes. E.g. if you are shipping 20161004, delete 20160720 because 20160720.1 exists.

The background-- jenkins installation, what's involved..

  • An appropriate .bash_profile -- executable (sigh), empty on linux/mac, built from Windows build procedure on Windows
  • A checked-out repo with appropriate tools somewhere. Symlinked from its tool directory, /dronin-tools ... Use appropriate magic on windows with mklink (something like cmd //c mklink //j /dronin-tools tools )
  • A configuration
<?xml version='1.0' encoding='UTF-8'?>
<matrix-project plugin="[email protected]">
  <actions/>
  <description>dRonin Branch Builds</description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="hudson.tasks.LogRotator">
        <daysToKeep>-1</daysToKeep>
        <numToKeep>37</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <com.coravy.hudson.plugins.github.GithubProjectProperty plugin="[email protected]">
      <projectUrl>http://github.com/d-ronin/dRonin/</projectUrl>
      <displayName></displayName>
    </com.coravy.hudson.plugins.github.GithubProjectProperty>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>sha1</name>
          <description>Branch name or SHA to build on.</description>
          <defaultValue>next</defaultValue>
        </hudson.model.StringParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
  </properties>
  <scm class="hudson.plugins.git.GitSCM" plugin="[email protected]">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <name>origin</name>
        <refspec>+refs/pull/*:refs/remotes/origin/pr/* +refs/heads/*:refs/remotes/origin/*</refspec>
        <url>http://github.com/d-ronin/dRonin/</url>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>${sha1}</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <submoduleCfg class="list"/>
    <extensions/>
  </scm>
  <canRoam>true</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>
    <hudson.triggers.TimerTrigger>
      <spec># 5:03 every day
3 5 * * *</spec>
    </hudson.triggers.TimerTrigger>
    <org.jenkinsci.plugins.ghprb.GhprbTrigger plugin="[email protected]">
      <spec>H/5 * * * *</spec>
      <latestVersion>3</latestVersion>
      <configVersion>3</configVersion>
      <adminlist>mlyle tracernz pug398</adminlist>
      <allowMembersOfWhitelistedOrgsAsAdmin>false</allowMembersOfWhitelistedOrgsAsAdmin>
      <orgslist>d-ronin</orgslist>
      <cron>H/5 * * * *</cron>
      <buildDescTemplate></buildDescTemplate>
      <onlyTriggerPhrase>true</onlyTriggerPhrase>
      <useGitHubHooks>true</useGitHubHooks>
      <permitAll>false</permitAll>
      <whitelist></whitelist>
      <autoCloseFailedPullRequests>false</autoCloseFailedPullRequests>
      <displayBuildErrorsOnDownstreamBuilds>false</displayBuildErrorsOnDownstreamBuilds>
      <whiteListTargetBranches>
        <org.jenkinsci.plugins.ghprb.GhprbBranch>
          <branch></branch>
        </org.jenkinsci.plugins.ghprb.GhprbBranch>
      </whiteListTargetBranches>
      <gitHubAuthId>xxxxxxxxxxx</gitHubAuthId>
      <triggerPhrase>.*build artifacts please.*</triggerPhrase>
      <skipBuildPhrase>.*\[skip\W+ci\].*</skipBuildPhrase>
      <extensions>
        <org.jenkinsci.plugins.ghprb.extensions.status.GhprbSimpleStatus>
          <commitStatusContext>artifacts</commitStatusContext>
          <triggeredStatus>triggered building artifacts</triggeredStatus>
          <startedStatus>artifacts building</startedStatus>
          <statusUrl></statusUrl>
          <addTestResults>false</addTestResults>
          <completedStatus>
            <org.jenkinsci.plugins.ghprb.extensions.comments.GhprbBuildResultMessage>
              <message>artifacts built</message>
              <result>SUCCESS</result>
            </org.jenkinsci.plugins.ghprb.extensions.comments.GhprbBuildResultMessage>
          </completedStatus>
        </org.jenkinsci.plugins.ghprb.extensions.status.GhprbSimpleStatus>
      </extensions>
    </org.jenkinsci.plugins.ghprb.GhprbTrigger>
  </triggers>
  <concurrentBuild>true</concurrentBuild>
  <axes>
    <hudson.matrix.LabelAxis>
      <name>Nodes</name>
      <values>
        <string>master</string>
        <string>osx</string>
        <string>winx86-neo</string>
      </values>
    </hudson.matrix.LabelAxis>
  </axes>
  <builders>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

if echo &quot;$NODE_NAME&quot; | grep &quot;winx86&quot; ; then
  mkdir -p build
  cmd //c rmdir //q //s build
fi

git clean -f -d -x -e tools</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

rm -f tools

if echo &quot;$NODE_NAME&quot; | grep &quot;winx86&quot; ; then
cmd //c mklink //j tools /dronin-tools
else 
ln -s /dronin-tools tools
fi</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

git reset --hard</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

GCS_BUILD_CONF=release FLIGHT_BUILD_CONF=release make -j3 all package_flight</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

if [ &quot;$NODE_NAME&quot; = &quot;master&quot; ] ; then
  make -j3 androidgcs
  ANDROIDGCS_BUILD_CONF=release make -j3 androidgcs
fi</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

if [ &quot;$NODE_NAME&quot; = &quot;master&quot; ] ; then
  make all_ut_run
fi</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

if echo &quot;$NODE_NAME&quot; | grep &quot;winx86&quot; ; then
  # Presently not supported on Windows
  EXPORT_SYMBOLS=YES make package_all_compress
else
  make package_all_compress
fi</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

make package_installer</command>
    </hudson.tasks.Shell>
    <hudson.tasks.Shell>
      <command>. ~/.bash_profile

mkdir -p build/artifacts
mv build/dronin*.zip build/dronin*.xz build/dRonin*.exe build/*.dmg build/dronin*.deb build/artifacts || true
mv build/package-*/dronin*.deb build/package-*/dRonin*.exe build/package-*/d*.dmg build/artifacts || true
mv build/dronin-*-breakpad.tar.xz  build/dronin-*-breakpad.zip dronin-*-symbols.tar.xz dronin-*-symbols.zip build/artifacts || true
mv build/androidgcs/bin/androidgcs*.apk build/artifacts || true

rm -f tools</command>
    </hudson.tasks.Shell>
  </builders>
  <publishers>
    <hudson.tasks.ArtifactArchiver>
      <artifacts>build/artifacts/*</artifacts>
      <allowEmptyArchive>false</allowEmptyArchive>
      <onlyIfSuccessful>true</onlyIfSuccessful>
      <fingerprint>true</fingerprint>
      <defaultExcludes>true</defaultExcludes>
      <caseSensitive>true</caseSensitive>
    </hudson.tasks.ArtifactArchiver>
    <org.jenkinsci.plugins.postbuildscript.PostBuildScript plugin="[email protected]">
      <buildSteps>
        <hudson.tasks.Shell>
          <command>if [ &quot;x$ghprbPullId&quot; != &quot;x&quot; ] ; then
    /home/mlyle/mkcomment.py
fi</command>
        </hudson.tasks.Shell>
      </buildSteps>
      <scriptOnlyIfSuccess>true</scriptOnlyIfSuccess>
      <scriptOnlyIfFailure>false</scriptOnlyIfFailure>
      <markBuildUnstable>false</markBuildUnstable>
      <executeOn>MATRIX</executeOn>
    </org.jenkinsci.plugins.postbuildscript.PostBuildScript>
    <hudson.plugins.ircbot.IrcPublisher plugin="[email protected]">
      <targets class="empty-list"/>
      <strategy>NEW_FAILURE_AND_FIXED</strategy>
      <notifyOnBuildStart>false</notifyOnBuildStart>
      <notifySuspects>false</notifySuspects>
      <notifyCulprits>false</notifyCulprits>
      <notifyFixers>false</notifyFixers>
      <notifyUpstreamCommitters>false</notifyUpstreamCommitters>
      <buildToChatNotifier class="hudson.plugins.im.build_notify.SummaryOnlyBuildToChatNotifier" plugin="[email protected]"/>
      <matrixMultiplier>ONLY_CONFIGURATIONS</matrixMultiplier>
      <channels/>
    </hudson.plugins.ircbot.IrcPublisher>
  </publishers>
  <buildWrappers/>
  <executionStrategy class="hudson.matrix.DefaultMatrixExecutionStrategyImpl">
    <runSequentially>false</runSequentially>
  </executionStrategy>
</matrix-project>
  • mkcomment.py:
#!/usr/bin/python

# ghprbTriggerAuthorLoginMention
# ghprbPullId
# BUILD_URL

import json
import requests

from os import environ

owner = 'd-ronin'
repo = 'dRonin'
issue = 356

token = 'XXXREDACTEDXXX'

url = 'https://api.github.com/repos/%s/%s/issues/%s/comments'%(owner, repo, environ['ghprbPullId'])

buildUrl = environ['BUILD_URL'] + 'Nodes=%s/artifact/build/artifacts/'

builders = { "windows" : "winx86-neo", "linux-x86_64" : "master", "macosx" : "osx" }

body = "Artifacts built, by request of %s\n\n" % (environ['ghprbTriggerAuthorLoginMention'])

for b in builders.keys():
    body += "* [%s](%s)\n"%(b, buildUrl%(builders[b]))

auth = requests.auth.HTTPBasicAuth('dronin-ci', token)

payload = { 'body' : body }

print "Posting to %s" % (url)

print "Body : %s" % (json.dumps(payload))

r = requests.post(url, data=json.dumps(payload), auth=auth)

print r

Clone this wiki locally