summaryrefslogtreecommitdiff
path: root/contrib/cirrus/cache_release_archive.sh
blob: 639bc98018a73b93871e08cb7e53e457f256c55c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/bin/bash

set -eo pipefail

source $(dirname $0)/lib.sh

req_env_var GOSRC

RELEASE_ARCHIVE_NAMES=""

handle_archive() {  # Assumed to be called with set +e
        TASK_NUMBER=$1
        PR_OR_BRANCH=$2
        CACHE_URL=$3
        ARCHIVE_NAME="$(basename $CACHE_URL)"
        req_env_var TASK_NUMBER PR_OR_BRANCH CACHE_URL ARCHIVE_NAME

        cd /tmp
        curl -sO "$CACHE_URL" || return $(warn 0 "Couldn't download file, skipping.")
        [[ -r "/tmp/$ARCHIVE_NAME" ]] || return $(warn 0 "Unreadable archive '/tmp/$ARCHIVE_NAME', skipping.")

        ZIPCOMMENT=$(unzip -qqz "$ARCHIVE_NAME" 2>/dev/null)  # noisy bugger
        if [[ "$?" -ne "0" ]] || [[ -z "$ZIPCOMMENT" ]]
        then
            return $(warn 0 "Could not unzip metadata from downloaded '/tmp/$ARCHIVE_NAME', skipping.")
        fi

        RELEASE_INFO=$(echo "$ZIPCOMMENT" | grep -m 1 'X-RELEASE-INFO:' | sed -r -e 's/X-RELEASE-INFO:\s*(.+)/\1/')
        if [[ "$?" -ne "0" ]] || [[ -z "$RELEASE_INFO" ]]
        then
            return $(warn 0 "Metadata empty or invalid: '$ZIPCOMMENT', skipping.")
        fi

        # e.g. libpod v1.3.1-166-g60df124e fedora 29 amd64
        # or   libpod v1.3.1-166-g60df124e   amd64
        FIELDS="RELEASE_BASENAME RELEASE_VERSION RELEASE_DIST RELEASE_DIST_VER RELEASE_ARCH"
        read $FIELDS <<< $RELEASE_INFO
        for f in $FIELDS
        do
            [[ -n "${!f}" ]] || return $(warn 0 "Expecting $f to be non-empty in metadata: '$RELEASE_INFO', skipping.")
        done

        echo -n "Preparing $RELEASE_BASENAME archive: "
        # Drop version number to enable "latest" representation
        # (version available w/in zip-file comment)
        RELEASE_ARCHIVE_NAME="${RELEASE_BASENAME}-${PR_OR_BRANCH}-${RELEASE_DIST}-${RELEASE_DIST_VER}-${RELEASE_ARCH}.zip"
        # Allow uploading all gathered files in parallel, later with gsutil.
        mv -v "$ARCHIVE_NAME" "/$RELEASE_ARCHIVE_NAME"
        RELEASE_ARCHIVE_NAMES="$RELEASE_ARCHIVE_NAMES $RELEASE_ARCHIVE_NAME"
}

make_release() {
    ARCHIVE_NAME="$1"
    req_env_var ARCHIVE_NAME

    # There's no actual testing of windows/darwin targets yet
    # but we still want to cross-compile and publish binaries
    if [[ "$SPECIALMODE" == "windows" ]] || [[ "$SPECIALMODE" == "darwin" ]]
    then
        RELFILE="podman-remote-${SPECIALMODE}.zip"
    elif [[ "$SPECIALMODE" == "none" ]]
    then
        RELFILE="podman.zip"
    else
        die 55 "$(basename $0) unable to handle \$SPECIALMODE=$SPECIALMODE for $ARCHIVE_NAME"
    fi
    echo "Calling make $RELFILE"
    cd $GOSRC
    make "$RELFILE"
    echo "Renaming archive so it can be identified/downloaded for publishing"
    mv -v "$RELFILE" "$ARCHIVE_NAME"
    echo "Success!"
}

[[ "$CI" == "true" ]] || \
    die 56 "$0 requires a Cirrus-CI cross-task cache to function"

cd $GOSRC
# Same script re-used for both uploading and downloading to avoid duplication
if [[ "$(basename $0)" == "cache_release_archive.sh" ]]
then
    # ref: https://cirrus-ci.org/guide/writing-tasks/#environment-variables
    req_env_var CI_NODE_INDEX CIRRUS_BUILD_ID
    # Use unique names for uncache_release_archives.sh to find/download them all
    ARCHIVE_NAME="build-${CIRRUS_BUILD_ID}-task-${CI_NODE_INDEX}.zip"
    make_release "$ARCHIVE_NAME"

    # ref: https://cirrus-ci.org/guide/writing-tasks/#http-cache
    URL="http://$CIRRUS_HTTP_CACHE_HOST/${ARCHIVE_NAME}"
    echo "Uploading $ARCHIVE_NAME to Cirrus-CI cache at $URL"
    curl -s -X POST --data-binary "@$ARCHIVE_NAME" "$URL"
elif [[ "$(basename $0)" == "uncache_release_archives.sh" ]]
then
    req_env_var CIRRUS_BUILD_ID CI_NODE_TOTAL GCPJSON GCPNAME GCPROJECT
    [[ "${CI_NODE_INDEX}" -eq  "$[CI_NODE_TOTAL-1]" ]] || \
        die 8 "The release task must be executed last to guarantee archive cache is complete"

    if [[ -n "$CIRRUS_PR" ]]
    then
        PR_OR_BRANCH="pr$CIRRUS_PR"
        BUCKET="libpod-pr-releases"
    elif [[ -n "$CIRRUS_BRANCH" ]]
    then
        PR_OR_BRANCH="$CIRRUS_BRANCH"
        BUCKET="libpod-$CIRRUS_BRANCH-releases"
    else
        die 10 "Expecting either \$CIRRUS_PR or \$CIRRUS_BRANCH to be non-empty."
    fi

    echo "Blindly downloading Cirrus-CI cache files for task (some will fail)."
    set +e  # Don't stop looping until all task's cache is attempted
    for (( task_number = 0 ; task_number < $CI_NODE_TOTAL ; task_number++ ))
    do
        ARCHIVE_NAME="build-${CIRRUS_BUILD_ID}-task-${task_number}.zip"
        URL="http://$CIRRUS_HTTP_CACHE_HOST/${ARCHIVE_NAME}"
        echo "Attempting to download cached archive from $URL"
        handle_archive "$task_number" "$PR_OR_BRANCH" "$URL"
        echo "----------------------------------------"
    done
    set -e

    [[ -n "$RELEASE_ARCHIVE_NAMES" ]] || \
        die 67 "Error: No release archives found in CI cache, expecting at least one."

    echo "Preparing to upload release archives."
    gcloud config set project "$GCPROJECT"
    echo "$GCPJSON" > /tmp/gcp.json
    gcloud auth activate-service-account --key-file=/tmp/gcp.json
    rm /tmp/gcp.json
    # handle_archive() placed all uploadable files under /
    gsutil -m cp /*.zip "gs://$BUCKET"  # Upload in parallel
    echo "Successfully uploaded archives:"
    for ARCHIVE_NAME in $RELEASE_ARCHIVE_NAMES
    do
        echo "    https://storage.cloud.google.com/$BUCKET/$ARCHIVE_NAME"
    done
    echo "These will remain available until automatic pruning by bucket policy."
else
    die 9 "I don't know what to do when called $0"
fi