blob: 5200357d73dfa47b115ab7adf41d4c4ffc883ebd [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2008, 2019 IBM Corporation and others.
This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
which accompanies this distribution, and is available at
https://www.eclipse.org/legal/epl-2.0/
SPDX-License-Identifier: EPL-2.0
Contributors:
IBM Corporation - initial API and implementation
-->
<project
name="signJarsInArchive"
default="signJarsInArchive"
basedir=".">
<!-- = = = standard properties pattern = = = -->
<!--
Note to be cross-platform, "environment variables" are only appropriate for
some variables, such as ones we create and set, since properties are case sensitive, even if
the environment variables on your operating system are not, e.g. it will
be ${env.Path} not ${env.PATH} on Windows -->
<property environment="env"/>
<!--
Let users override standard properties, if desired.
If directory, file, or some properties do not exist,
then standard properties will be used.
-->
<property file="${env.LOCAL_BUILD_PROPERTIES_DIR}/${ant.project.name}.properties"/>
<!-- = = = end standard properties pattern = = = -->
<!--
======= Primary task ========
-->
<!--
== signJarsInArchive ==
-->
<target
name="signJarsInArchive"
depends="check.sign"
if="doSign">
<!--
Fail fast if variables are not provided as expected.
remember, these "fast fails" should not go at top of file, out of a target,
as I usually do, since sometimes this script is re-entered with inheritAll=false,
in which case some _will_ be undefined (though they don't need to before that caes)
-->
<fail
unless="buildDirectory"
message="buildDirectory must be specified by caller"/>
<!-- Fail fast if variables are not provided as expected -->
<fail
unless="archiveName"
message="archiveName must be specified by caller"/>
<fail
unless="buildLabel"
message="buildLabel must be specified by caller"/>
<fail
unless="buildId"
message="buildId must be specified by caller"/>
<!-- Our specific directory in the signing area -->
<property
name="stagingDirectory"
value="/opt/public/download-staging.priv/webtools/${archiveName}"/>
<property
name="signingHistory"
value="${buildDirectory}/signing-${archiveName}.log"/>
<property
name="outputFile"
value="${stagingDirectory}/${archiveName}"/>
<echo message="Beginning signing process"/>
<!--copy zip file to staging directory-->
<!-- but first make positive that staging area is completely clean, incase used before. In future, might want to fail if it's not? -->
<echo message="Making staging directory: ${stagingDirectory}"/>
<mkdir dir="${stagingDirectory}"/>
<echo message="Deleting any possible files in staging area just in case."/>
<delete includeemptydirs="true" deleteonexit="true">
<fileset dir="${stagingDirectory}">
</fileset>
</delete>
<echo message="Copying zip file to staging directory"/>
<echo message="zip file: ${buildDirectory}/${buildLabel}/${archiveName}"/>
<echo message="staging directory: ${stagingDirectory}"/>
<copy
verbose="true"
file="${buildDirectory}/${buildLabel}/${archiveName}"
todir="${stagingDirectory}"/>
<!-- make sure it has correct permissions. Not sure this is still required? not good to give "other" write permission!?-->
<chmod
file="${outputFile}"
perm="ugo+rw"
verbose="true"/>
<!-- establish Original Attributes -->
<!-- this first count is just to confirm there is only one file there ...
in future, we may want to fail here, if not?-->
<resourcecount property="originalNFiles">
<fileset dir="${stagingDirectory}">
</fileset>
</resourcecount>
<echo message="original Number of Files: ${originalNFiles}"/>
<exec
executable="ls"
failonerror="true"
outputProperty="originalAttributes">
<arg line="-l ${outputFile}"/>
</exec>
<echo message="initial originalAttributes: ${originalAttributes}"/>
<!--invoke sign script and wait. Default action is to put back into stagingDirectory, with same name.
Note: we do not capture outptut here (though, we used to). It is never interesting. Just says "job
added to que". Does not capture any interesting success or failure information. Need to see
signing log, for that. Also note: we 'failonerror' since otherwise, if there was a failure,
we'd likely loop forever in "waitForChangedAttributes". Failure to execute is rare, but can
happen, e.g. when script changes, or permissions on file system change, and is hard to
diagnose if things continue trying to run. A "success" here, does not mean signing
was successful ... just means the job was successfully added to signing queue.
-->
<echo message="invoke sign script and wait"/>
<exec
executable="sign"
failonerror="true">
<arg line="${outputFile} nomail"/>
</exec>
<!--Wait for signed build to be available -->
<antcall target="waitForChangedAttributes"/>
<!--copy zip back to build machine -->
<echo message="copy zip back to build machine"/>
<copy
verbose="true"
file="${outputFile}"
todir="${buildDirectory}/${buildLabel}"/>
<!--delete signing directory (and zip file) -->
<echo message="delete file in signing directory, on build.eclipse.org"/>
<delete verbose="true">
<fileset dir="${stagingDirectory}">
</fileset>
</delete>
</target>
<!--
======= Utility tasks ========
-->
<!--
== compareAttributes ==
The compareAttributes task and the waitForChangedAttributes task call each other repeatedly,
until attributes are changed.
TODO: we might have to adjust "outer" timeouts, if this takes a lot longer,
and we might want to have our own time or loop checks here.
-->
<target name="compareAttributes">
<!--poll file for change in attributes-->
<echo message="Polled Number of Files: ${polledNFiles} (pre-poll)"/>
<resourcecount property="polledNFiles">
<fileset dir="${stagingDirectory}">
</fileset>
</resourcecount>
<echo message="Polled Number of Files: ${polledNFiles} (post-poll)"/>
<echo message="polled: ${polledAttributes} (pre-poll)"/>
<exec
executable="ls"
outputProperty="polledAttributes">
<arg line="-l ${outputFile}"/>
</exec>
<echo message="original: ${originalAttributes}"/>
<echo message="polled: ${polledAttributes} (post-poll)"/>
<!--
We compare number of files, and attributes, for added safety. May not be necessary.
There should only be 1 files there.
Once there signing process starts, there will be a directory and file made in the
staging area ... where the work is done ... and then that renamed to original name,
hence replacing it, and it will have a new "owner" and a new file size.
-->
<condition property="attributesChanged">
<and>
<equals
arg1="1"
arg2="${polledNFiles}"
trim="true"/>
<not>
<equals
arg1="${originalAttributes}"
arg2="${polledAttributes}"
trim="true"/>
</not>
</and>
</condition>
<!-- here we, effectively, call ourselves recursively. In some cases (such as when signing que hangs, and never signs files), this recursion eventually causes an "out of memory" error, since the stack gets larger and larger -->
<antcall target="waitForChangedAttributes"/>
</target>
<!--
== waitForChangedAttributes ==
Wait and then compare attributes of file to see if changed.
inheritAll: false - this is critical to the workings. Otherwise it "keeps" the same
values it saw before, and then never notices a change.
Note too we check first, and then sleep. I think there are are some cases where
a (small) file is signed so quickly, it's already been signed by the time an initial
sleep is over ... and there's something, I think, that causes that case to not work (it
just loops then, never detecting change) I suspect this means the initial 'originalAttributes'
are not set as I think they are ... but, hopefully sleeping afterwards will help avoid
those "missed" cases.
-->
<target
name="waitForChangedAttributes"
unless="attributesChanged">
<sleep seconds="180"/>
<antcall
target="compareAttributes"
inheritAll="false">
<param
name="originalAttributes"
value="${originalAttributes}"/>
<param
name="stagingDirectory"
value="${stagingDirectory}"/>
<param
name="outputFile"
value="${outputFile}"/>
</antcall>
</target>
<!--
== check.sign ==
The property 'sign' is the critical attribute that determines if signing will be done.
If false, or absent, signing is not done.
We do not only rely on absence, so the "master properties" can set to false, and individual
components remain set to 'true' (for example, to have quick local builds, without changing
component properties - currently used "SKIP_JAR_SIGNING" instead, but that
doesn't feel quite right, so may change in future. SKIP_JAR_SIGNING can be
set as env variable or ant variable.
-->
<target name="check.sign">
<echo
level="info"
message="sign: ${sign}"/>
<echo
level="info"
message="env skip jar signing: ${env.SKIP_JAR_SIGNING}"/>
<echo
level="info"
message="skip jar signing: ${SKIP_JAR_SIGNING}"/>
<condition property="doSign">
<and>
<equals
arg1="${sign}"
arg2="true"
trim="true"
casesensitive="false"/>
<not>
<equals
arg1="${env.SKIP_JAR_SIGNING}"
arg2="true"
trim="true"
casesensitive="false"/>
</not>
<not>
<equals
arg1="${SKIP_JAR_SIGNING}"
arg2="true"
trim="true"
casesensitive="false"/>
</not>
</and>
</condition>
</target>
</project>