-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy path.travis.yml
178 lines (164 loc) · 13.5 KB
/
.travis.yml
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
sudo: required
language: go
matrix:
include:
- os: linux
sudo: required
go: "1.18"
services: docker
dist: xenial
git:
depth: 3
notifications:
email: false
webhooks:
urls:
# travis2slack webhook to enable DMs on openwhisk-team.slack.com to PR authors with TravisCI results
secure: "NaDCtHwbFUEy0h0u/QrAt395o0/9FstJ5/Tv4uBSLCBdaUNU+0q6/RXVH76dKbujoxrLded2gyeJSAbI4kl4SM7FyilSHzKTikF0VsgM3G5veh65tVY5ztsvl40hDmK2E/PmWI3HkZNeWJO32WjraqPmhSWL0BZOWhA/4gJSCIsLnNRQXmpZoDqC7V8IG1BWYGwd5qcNkEjItLjYCUy1s2K8bj3QmhshYRVLTNbXxh0yJVKjM04I+bWhMXqvL8GS55qeicJ3fUwm5g1PDVCtzxLwAHCPo2jusjtNSnV+BaZgMBSahv3MD7ApxfF58e1buejggH3qZAhNGccC4bYJCahqVv/KKoA10kO6exH5iGwlHPWQTjMuF++PHmAk+FeQ1jh+JoUSBnIHExPnaD4CQIArHvUuQom+WJBnOz+L1H755VyPGzeDQ+ZUDlhOiQ6CDP/sqaRH3Wmo4IzhsqTsLaQs0dS1YeEWOS8gcawwNTVf/WtqiedYu24rQN9RiUXelRoEaXJy/pldb2KpyQRo2hbKoStDDB5fEij1xyGsj4kSXZ8uk5G10oDGnZYd+okduzJazN8wr0flrLvH32DRgDZDcG/D90I19JmqqfqbcG/SEmhxTikHZeVQd5DfWcqssLvWNrtQa/EJgAQkmZ2gaSsZ73AvPk/KyMV30+m8xTU="
# The complete sequence of phases of the lifecycle:
# ---------------------------------------------------------
# before_install
# install
# before_script
# script
# before_cache (OPTIONAL) (if and only if caching is effective)
# after_success (or after_failure)
# before_deploy (OPTIONAL) (if and only if deployment is active)
# deploy (OPTIONAL)
# after_deploy (OPTIONAL) (if and only if deployment is active)
# after_script
before_install:
- "./tools/travis/cloneutils.sh"
- sudo apt-get install tree
# Install tools we use for linting and unit/integration testing
# TODO: build.gradle (gradlew) already installs 'golint' and runs linting
# in the `goLint` task; see if we can remove here.
# TODO: The "gogradle" plugin in build.gradle (gradlew) already provides a
# task called "goTest" which runs all `unit` tests. See if we can use that
# instead and only run `integration` tests here.
install:
- export DEPLOY_BUILD_READY=false
- go get -u golang.org/x/lint/golint
- go get -u github.com/stretchr/testify
# Identify Golang files that are not properly formatted
# TODO: See if we can create custom tasks to perform this in build.gradle
# as a custom `goFmt` task
before_script:
- GO_FILES=$(find . -iname '*.go' -type f -not -path "./wski18n/i18n_resources.go")
- export BAD_GO=$(gofmt -s -l $(echo $GO_FILES))
- echo "["$BAD_GO"]"
#- test -z "$BAD_GO"
#- test -z "$(gofmt -s -l $(echo $GO_FILES))"
# Clone and build the OpenWhisk platform (i.e., apache/openwhisk)
# and then use Ansible to deploy it and prepare it to run our
# integration tests.
# TODO: Do not use Makefile for running integration tests (in script.sh);
# change to using gradle wrapper
script:
- echo "Installing and building OpenWhisk platform using Ansible..."
- "./tools/travis/showenv.sh"
# - "./tools/travis/script.sh"
# after_success:
# - DEPLOY_BUILD_READY=true
# - if [ "$TRAVIS_EVENT_TYPE" == "cron" ] ; then
# export DEPLOY_BUILD_READY=false;
# fi
# If this is a "tagged" GitHub build, then use Gradle Wrapper
# to build binaries for all supported OS platforms and architectures.
# The result would be a "/build" directory that has a subdirectory named
# for each supported GOOS/GOARCH
before_deploy:
- export build_file_name=wskdeploy
- go get github.com/inconshreveable/mousetrap
- export GIT_TAG="latest"
- export TAG=false
- if [ ! -z "$TRAVIS_TAG" ] ; then
export GIT_TAG=$TRAVIS_TAG;
export TAG=true;
fi
- echo "Calling Gradle Wrapper task to build and 'releaseBinaries'..."
- "./tools/travis/showenv.sh"
- ./gradlew --console=plain releaseBinaries -PpackageVersion=$GIT_TAG -PgitCommit=$(git rev-parse HEAD) -PbuildDate=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
- echo "Build binaries and release archives created:"
- tree /build
- tree /release
- export RELEASE_PKG_FILE="$(cd "$TRAVIS_BUILD_DIR/release" && ls ${zip_file_name}-*.tgz ${zip_file_name}-*.zip)"
- echo "Deploying "$RELEASE_PKG_FILE" to GitHub releases..."
- if [ "$TRAVIS_BRANCH" == "master" ] && [ "$TRAVIS_EVENT_TYPE" == "push" ] && [ "$TRAVIS_OS_NAME" == "linux" ] ; then
git config --global user.email "[email protected]";
git config --global user.name "Travis CI";
git tag -d $GIT_TAG;
git push -q https://[email protected]/apache/openwhisk-wskdeploy :refs/tags/$GIT_TAG;
GIT_COMMITTER_DATE="$(git show --format=%aD | head -1)" git tag $GIT_TAG -a -m "Generated tag from Travis CI build $TRAVIS_BUILD_NUMBER";
git push -f -q https://[email protected]/apache/openwhisk-wskdeploy $GIT_TAG;
fi
- echo "Completing before_deploy stage"
# Utilize two providers to create a github release and publish a docker image.
# For information on the "releases" provider,
# see https://docs.travis-ci.com/user/deployment/releases/
deploy:
- provider: releases
api_key:
secure: aQGcP7XKlgZEFZ57y4RzYRHfQAM5HEdaa7Y/vTxNepIsE7zY2945qT99UJnU1hfhSjP9jO5eNlHzo+AqJoUx70+iUIhMTyOp39Qp7wb74OKolkXwcntufzP7Ocron5IYUE311tf/kic3vRb5cwoaE2lGfx5PdCuozVjgpsDbIRvV5quQzNr68Toqe+yegKwAhprYRWHPnuIqGbkfa83csqFv6m0viC/gvtFOCB9/4zGCqk/K3CKrcr/5GvnFPxJoaJNfFA6umSZ9VaJjbIJmcXGD3nU+rWP0uEpvzGKIMYhmQq/0JuUTgvh4jnnT4OVZeTh6pMaUqtWH+3HDrOiLAiLjcfeT91j7ZXPnx8LvM6SuoRlvRCuXA2FYx9mz2Vx0TWV5TMqhj3okVO/CvvnMMWwKWOUDD/nSMLy93BM40NjD7zimGjocPsGAjTT9H1PSfau3fiiMjg6iMRWjUTfNY5ra5Wgb7W5G37XaCBJDBZL77Blq/tNWdV5qW4A3l4FWnH+LwOdTdhU35Lr5JWzMuEDdkvVgEv8AQjb07P/ODtBW6z3GRv9Rslg9T9ylxkgJpXoYwdXCbtYU8GNcFdJiDpTaVHrkMeLvHrBTRrDCSnCnRFc3AxsUtLklo7R/EX1wUoX+QcAGjh/AmJ4nJVP1C09913fx96WczkRX6ANg2Mw=
file_glob: true
file:
- release/${zip_file_name}-*.tgz
- release/${zip_file_name}-*.zip
overwrite: true
skip_cleanup: true
target_commitish: $TRAVIS_COMMIT
tag_name: $GIT_TAG
on:
repo: apache/openwhisk-wskdeploy
tags: $TAG
condition: "$DEPLOY_BUILD_READY = true"
- provider: script
skip_cleanup: true
script: "./tools/travis/docker/publish.sh openwhisk wskdeploy ${TRAVIS_TAG}"
on:
repo: apache/openwhisk-wskdeploy
tags: true
condition: "$DEPLOY_BUILD_READY = true"
# Clean up wskdeploy binary (single)
# Fundamentally, remove both /build and /release directory trees and contents
# TODO: See if this is really needed in Travis environments as the
# Makefile is not used elsewhere here (especially if we do not use th
# build_tag_release.sh script) as it is for Windows developers primarily
# and we are building using Linux.
# after_script:
# - make clean
# - tree /build
# - tree /release
env:
global:
- BLUEMIX_APIHOST=openwhisk.ng.bluemix.net
- secure: ClspSsyTZdDNen+qZFAN37gP6T0HO4hthuDMb/w/xekznNazoKajTh1XQg5ccQ9o7BuXt5/Mrv8ZbHIg4GQrW4puLxkqfdd956szTDznxU0zgOK23YwdPhf74Uga2ucXOJcNeOcfrgR6jtTQZ2TbS2u11PjC6yp7KKY1vYEJXsbTkJ761H7Geu4qY7PmZ0x/Srw+DwiR1ZXH/PKlZIHbOF1m6F5zkTWLpN+/8YcRUxYOs/oGtYqqz0TxNDmlUE0lh6El8iUtAGrCGxdmLK+FSPAMk4ILJOMoqeIzk/eeNr+w8eXhG29zJRz++e2jxr1kXc0OknOXroO9jmv+G6IicRrWG/Em4n/tDeuehFdRmdRDBoKSczpx3ws9qjzPahMJ5QJP3r19e8uQnSgHPJ00d4+H8P1cf46TucQNLQGuoeap+PhPTy69spXpwdyze50DaoQGVe7+nmO0RUJ13LUJZZDz2EFQg5jjx3cSwQRbT4rvMCCl1ByiyN4gJ3jwTEdPtXVVJaub9Z4aDk8GxROC/RT1SGhQmnfnMg0+H/chHpDo4M5mrNgYwRdMzgJScgRl4ShyZQF4fjvX8oT2KBbu5VGUslew8/Cgi4ezdXOJ6IGGmjzf0kdq+NLwQBKtAV/8YEWFDCTG3k1uUaw4/YlTq26kUwTqnBx4tT7/8Sh0uRI=
- secure: f8CKUxpI0xp2N78ifCQCpOg0/LAzZv7cDhuYZvWB++LJ1tdwN+aHxYCRaDLNI49fogDqCoeIcJCy2uVCmNGEXwcUsGJ0Z28qvRsewsgwwnrny8E+NyqmV/DFfAWvR095lwfQsBiqdGJLcOU2ZXvog3+y2p/I14LCInkThLJSMjA56IDqYkbp8OUy5ncLUZ726PVb/N40hw5TTpgf+yKcHXlXOmRYwH54jvxduxz0RnDSpFuV9k2qCMP10f2GZcWhFUCdOU8kYrTsMbo0Mk712Q1N49V/9QB9ZrMGIbQqufFvp+E/Wf/mL7ANyRmG0C6eOnVrtsnhjzVVJrpv0oyV53HOwmL1FrMzJE65V35B0fi8fUgslEgxnYLXeCxRetOFOyJIjTA/wIZ7uyWPrXQa+QbcQixMLYn4xe7iJHuA+d1u3b5SOcjD+eBa/s+ihISwQoKkeDja6cL+5bROTcccE0hNC4ivadPKsosGdCDdSCQhQlzGbXDGx0psYe7/9J0tGgfPsnPdn1TFyTvJRjGAQyZVULGltgAFBxcVNAoeeez36cMUVmnqsmR0wf1XHNQhCwBuBY4ujyQC74ichPgDYByhLGeQ7aiHBqt1n58AidB9eWjhjvrfEEni/S28bS2StqZ+uSQKHkdgFtWoCRnBbw+p0cdPfyO8g8vIlJpaAKY=
# Cloudant
- secure: NVP+kpAlZc1GdM2Er0EbWvG1ak6iIKgui6BrBq8lm+wSjkDXGtEnkvvvE8+IrYIvZaKurT71M0n4MfrQhEDUmxhXsQSP+ZPEB5VJD182OWMD4zfqsYmaqOsur50MOHeb4ZO6Bv0SrnCSvIcPqchXEqg3S2aYzSYtFjqW5jPECO8FOnCUu9STGN3bo2XJsMWpnhJrO+u9AYf/D6+LlD4+839gMUVUWy/vU4FTCsS5lTBwIwPV/0IBa1ivp8roteG4LOJH5LHHnUekgUt+wZgdmrny6hUTn9JMS2TzOgctHBoAiNyLzeXwvJSOPQ6w8gBFHYW1R5HlF64uaovqNnY6qLrtKyIIKNfYjqiFg250siEdm9FaFJlqqOOof6M8gfU1Ob/Ax0GthyHqjUcgNeUXd7K1BzDNWRC34wTcqXRlZyO8IvqYI21Zm1mDSNTRRA4Jw/Ajx7RLZknm5bOYwFblWCk06ULVYjhyIUcxGFUQqeIr3CQHu/V7BJthVtNPFTgOFLp8eFMaG2ACZcgS4wKyfvu5IQa1q4noWVrB8Yprft1x9+20lX4L+N//QJZLpjGX23OaBZrNMIgS6yPuD3e4UrlqOxbJC/BO1kpjLx+REdUtzp8dDCWpHd5ISS8V1Yr3p9Gk8Q6lnR0MIsGEW1t/3qMaEgw69OiWtV86f+zlBTs=
- secure: pQhw+jUrDK8+s8BV/5y7CXTfdzGxit0Ej1BAJcs9xcjIpLFFW1+d+n2bcXVk8F43lhsHeilmwfUnxnHkI48qGED4HBZ4cUpI6Ka69oP+hRZdBXQLHysZIHpSBC1vWPCN1SSV/wSc4bNTXopyr0XmtY/aRpOusunz8uIj218/44Z3S3lgNqLeMHaQjzo3/Dh0IXtTYYfdnHzMB/9z3WvS3ycZ5OfdWnNWZT4OEw1NIESjFe/+g/ioQLq16BtIIxFq3+R4ujvUSxZCuOa6V8636hs+DvBZAwBkUljNCgR8CCzFMOrYcqzViCmiNHmIH7xkNWyVCQyB2xLk4lSkavI04wLTajqz1bvDbSZN5zxcz7oSkeg1ng3waMSDEPuQBVj6IHq3LnNN81kCI1Fyx9stimR5qA0GGzayG1OjA5tlxEsqgv0lu87MWj2KevVNcpLdyJQ8h0AWknPAhliCiGINSZz5y96yN8P2HIIvh0Ioh0coty6wZNsskfMrifpoBrgRDHseb+7jnj6KYdtxse0dLVSCo07Brqhp4N1dvYnqxgh71LhuDVe+Yocu4hU0EtT7hOgoP/tl5XNTQ0fQCB3TdowZ+7QFkcv7z3FJjOI2mL6qXKQi8Cdi/624vT8mKVIdI8yNbymyhIVAhG8zapQ+3kObLBAU22xvsUMztds2EFE=
# MessageHub
- secure: caCbpNxXM+wn98yRhavvb9fkY3pH4Dssr9zbIBVdO3Vtgnii+DYjj2i5ZL0zoXAQUJxyFx97kcO+KbB4OnaEWxPJ6hZiygtosuIccZIzhZNFp1NnFxsPQgIXjD7j71Nc6OcOQed56GbItmPSrmzcMyYYtkifvf8cAxoHVwqsYgGx65E88FPaBM86PUyKbNR5nBSVcx5dpFlJ/E2CmNkG5DnW/o1u4+mJvOrgR827MctO2AEUMTLDOCuU1nxGJciM7bBwcKVL09/fC8RAF0AXrGabOxlhZGhVp+5K/ifzNoAk+l5WTDP8vNI2H/rWzfsat5oqCy2SHjs5l1rHIei9Wy6QfPSDA6e5wlNs1XzT2DnO6sLmCxHTBv/+GrF/Glr50FaTuPlYYBjt626WwEiJIJvmsPMziVnY1cjRonz0Owk23TCcpjDM/3IIAfcbI/ZKfHRp+bdehMxAqMGxuLWCV/6lX+QV0tlPun2t4TwrZlTNmQPE+zaLgdF36vfJdwVfx3+2XkHn1aYNq1LJKuwYKBPjUdUU9VcVcdErFKyNa7pFoSjE9tfJrP+B1xilEEPDAnrNlEp+i1h1FS3VGRBNlej72t3Wt0q5/UQEulinUgsKm51nGvNGrvwRImzyS8aq73rSJkac8/nXIw9m9DtWugMEMTnMBs0j2MxTsAfR6SQ=
- secure: 15ImIPDIDLZQbHMjPaY9Yx//Z7qoxS1A2J6NiZaGqEZXOfksskhRlLnxW2GIvy1wBEGMICevMqBWevG5/6csPwXzBe9nrqkfnGOYN7nakttZWHHqU7Jh5YnpCfzeyHzfxVtJKuB/vJvxE6Hp34aqwIAQL1R13Ci0BNAuxPjnhpIGf7b9wXjX3mQ24XVPC9smMeUCE66aZ9BxGkGM5KzCezdLvpWV7Mq0y6xbPFzS/1oZeXrrNqaVgLKXGjnumJNJ+Mf75tJj2Q2hMoGHcTY+FOiAz6ueIuNR6ZKHyHGYpo+PAZUMlpC/9P6tCjOegx82EWfKUquNOh0rJcGOoFWrcuQ8FBO7/qSA1KbzeW7Rs9mL+ZkxqRC6SbFoe39Wda7/PE625JTeocsNbvacbEKwPLtLgDo3NJi3Lt0aEi/oUVaAEgiFZh5GchfDD8S2dTYt+TnaKjzKou7vJ6mf1FeKBqLH8MO+lbfez1pMvUsoXzFoYjG89Uy57x+0DUE9492Tr5wDeIbsVngxDkMye98hAGgsu1qTA7/+vm94HYrTLw+7HrJh1FoNfGnDmEpbLmBXCBRLj7TFL8QoV3m3uLwWE7gU63VYAyuNKFnDRrWXndmlakjHQSpejGWwPaQgvLJwS9Dm3m28NkWr1j5c3QsJcGps8iigRdgjeDCepOjF6G8=
# DockerHub
- secure: "YwccNIsFzZ/BZkM2Y1sHVjz6AfdrkjetltmwpIMUa4w3skKv4JCtrtqx6toLMO3O8sgqRhXoJsVANknoINw3y6U7KNq4J5noQff0wR9tuwvpZivxLQSYIqHB0sEwZ2b8t1u3axyujc9JEgCjaDc6qkgEUq5rhLsP5xkHM0bZCoJ4cnBttrC0Efv+T5jhXMx9fsEVQJhiqkKRBSWVgpF4NIQsWFWXHQC/KqSU0I6p/ztpOrDGWvM8wYlNR8TrDgoIX4XUiKTdicECHCWCAf6izZcYF9VwUeHlur7weMtE8IE2s2kthsZ2WIe4wIDQU1xbIUEnhYRNoxbzV1+jRkJ0MnzsV80Iq1z9QWFmSyb6VWQhtV0PfYyrepp8LtV5LcvrGUzwALo8FHzQUHTWi5SyTOVARAIV+luh8Rr7pXzkzwCUdDyu1Qs9gYtksEmCYrzBjqcyGlK53SN7PAKFeE/yt8DUqhB1bvCSRwbUINo4Ua36d7V4hkk1RKdN8k8ER4kgTzoCyV/6vJrN6G7Tc0Vst5fyfnR0O4tnetMnsX4Opwas3DFTW6gzBrVcTO8Dcf1jdJVfUXeeDbkx1auv11Xn2YodKJ+t/qoC9z6X7FftU2PXJwJxWCMw6ubnIFMMGfjwFN3f7gJBuztiVBczRYE3wb3alv0hz1xdtdLeTClDW/E="
- secure: "lnMMHCtl/ttDmA7tIFkj5TwXmWr46+bVDm8hRD9VI8+7cMnCAZb3MZ+2Nr7rpyi7YhklOAGW6F9vMIlWQQUiaEezpIe/4xmWDw9U4SmNhasi4gHw1Ux+BqV7xOY87Rhma67JfaToddMuhXZqjxMP3ux+oq245dTKEAh4bPjF9YnIoFl8UdZMrFykAS6uW/ON1jx49weQhjBR0uZBFNIvmorWiR1SmEPMTUik9BNh6Fdu9+3pb50UVN7TTNM9uIuOkvlUAdTBLC4kDajvKfM7ewy7rgnQlmhVvwV+jj3lmxxarU3jauNELGsI3PJnNpkHvoV9u2TGaDzwzDhQj1+JWq5eXE08N9vAZK27ohFxjDpSxPm681uek358tjagIF6QU56RohIOse4U/8Y5rawyD7ISXuDXqjLBMzncPr3Dz69wtenIqRdW72BAh+5O7p1RW+SX/lVAUBSSflQaLEKrntm17Ub2XE/TAx/bHq7xIoVZwBL7DrhdHUl6c3qfW7fwbHt1GU5pFW91mAbuLBpJV+fCJVrMOYU7ZOsSArGO9bbMU0IxjIB1QU9/BUE/aXqpyIsV6deP5QxqNj8IUVdld3N7GzSSxfILvQ0YlAlUquYM4eobNB4+cGZHOn+ermWHP39osXOMuufewXH+1y3zCiIDXCrhW6cbbx+8UHMO6tU="
# API_KEY used to generate the "latest" tag automatically
- secure: CHEYJanoGBV2W9LqBbnG312cOBj4FIWeiLLjfult/VDcjBlAQ71EzpBEv+H9c5J5ZmeRouQ3+dUC2wCJTCeTdzAOIi9Qci7tvTT8yYPShqGS3R1q+Hx1VBaGZhEDpxDcUDDGETBOQD6du7OTKOy+4bW0EdgZA6XENcIQNp5lCPVA2BMp8wI4vUgydbK3Po1vbj4KauBtk+XPU7cUkTxtw/QUyC5Eih6QphVovBIIngBSP917sO0ENwQHjOOkCb0rG1b5OnrAMOQSbpQsVgblv8caKINqnLG5aePN3YJCB5AFzXtQI515RQ9Tf8mX1XSceFtPwAfJhqLw8kHCoiu/ptLi/rxhuv1DTD+t+Y7413bMg/qIP08KKjyj+ScyeMRVnPEfNRC+z98Ka55FDhid9+FDx0uQ7ICDpi/TkCv8GDStk55vkSp3tYfNbORk453y4K6Yf7eS041ugfC3KejlmU2IPulwxQCFjFDZl7JMZo5NMOqBj6RUStWiF3DlxcM2M0I97B2cycwL6jTOlvFJUEFPoU9UIN9ICEYRdY33nxyG5qr+ymq0YgmZqmcjK3dGd5j32xXMqsDO+vrG+CnEpwht7uo6IQWYD44qsixe8J4HcoSYkm901mQYqT7VpNy6BXqHjPBSFUYkHaV/whT6QtCxKaaa7dg0s/jqi/zAnQY=
- zip_file_name=openwhisk_wskdeploy