Skip to content

Commit

Permalink
Merge pull request nmallya#1 from nmallya/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
nmallya authored Oct 15, 2017
2 parents d0543d5 + 8e77843 commit 6ad9f9f
Show file tree
Hide file tree
Showing 8 changed files with 298 additions and 11 deletions.
27 changes: 19 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,10 @@ jobs:
paths:
- ./vendor/bundle
key: v1-dependencies-{{ checksum "Gemfile.lock" }}
# - run: chmod +x ./.circleci/run_tests.sh
# - run: ./.circleci/run_tests.sh

# - run: bundle exec rake db:create db:migrate db:seed
# - run: bundle exec rspec
parallelism: 1

# push to Google Container Registry (GCR)
push-qa-server:
deploy-qa-server:
docker:
- image: turbinelabs/gcloud-build:0.12.4
requires:
Expand All @@ -43,9 +38,25 @@ jobs:
- run: docker build -t helloworldapp -f ./Dockerfile.gcloud .
- run: docker tag helloworldapp gcr.io/circle-agent/helloworldapp:$CIRCLE_SHA1
- run: gcloud docker -- push gcr.io/circle-agent/helloworldapp:$CIRCLE_SHA1
- run: chmod +x ./.circleci/deploy_qa.sh
- run: ./.circleci/deploy_qa.sh
# - run: chmod +x ./.circleci/deploy_qa.sh
# - run: ./.circleci/deploy_qa.sh

deploy-staging-server:
docker:
- image: turbinelabs/gcloud-build:0.12.4
requires:
- build
environment:
DEBIAN_FRONTEND: noninteractive
steps:
- checkout
- setup_remote_docker
- run: openrc boot
- run: docker build -t helloworldapp -f ./Dockerfile.gcloud .
- run: docker tag helloworldapp gcr.io/circle-agent/helloworldapp:$CIRCLE_SHA1
- run: gcloud docker -- push gcr.io/circle-agent/helloworldapp:$CIRCLE_SHA1
# - run: chmod +x ./.circleci/deploy_staging.sh
# - run: ./.circleci/deploy_stagin.sh

# # Deploy to GKE
# deploy-qa-server:
Expand Down
2 changes: 1 addition & 1 deletion .circleci/deploy_qa.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
echo ${GOOGLE_AUTH} | base64 -d > ${HOME}/gcp-key.json
gcloud auth activate-service-account --key-file ${HOME}/gcp-key.json
gcloud config set project circle-agent
gcloud container clusters get-credentials circlecicluster --zone us-central1-a --project circle-agent
gcloud container clusters get-credentials circleciqacluster --zone us-central1-a --project circle-agent


echo 'Updating web deployment image'
Expand Down
20 changes: 20 additions & 0 deletions .circleci/deploy_staging.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
echo ${GOOGLE_AUTH} | base64 -d > ${HOME}/gcp-key.json
gcloud auth activate-service-account --key-file ${HOME}/gcp-key.json
gcloud config set project circle-agent
gcloud container clusters get-credentials circlecistagingcluster --zone us-central1-a --project circle-agent


echo 'Updating web deployment image'
echo "Pushing image: web=gcr.io/circle-agent/helloworldapp:$CIRCLE_SHA1"
kubectl set image deployment web web=gcr.io/circle-agent/helloworldapp:$CIRCLE_SHA1 --record
kubectl rollout status deployment web
echo 'Web deployment image updated'


# echo 'kubectl proxy '
# kubectl proxy --address 0.0.0.0 --accept-hosts '.*' &
# sleep 6
#
# echo 'curling now...'
# curl http://localhost:8001/api/v1
2 changes: 1 addition & 1 deletion app/views/welcome/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<h1>Welcome</h1>
<p>This tutorial helps with doing circleci builds and deployments via Google Home </p>
<h2>This tutorial shows how we can use Google Home to deploy applications to Google Container Engine with CircleCI</h2>
201 changes: 201 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
'use strict';

const functions = require('firebase-functions'); // Cloud Functions for Firebase library
const DialogflowApp = require('actions-on-google').DialogflowApp; // Google Assistant helper library

const googleAssistantRequest = 'google'; // Constant to identify Google Assistant requests

exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
console.log('Request headers: ' + JSON.stringify(request.headers));
console.log('Request body: ' + JSON.stringify(request.body));

// An action is a string used to identify what needs to be done in fulfillment
let action = request.body.result.action; // https://dialogflow.com/docs/actions-and-parameters

// Parameters are any entites that Dialogflow has extracted from the request.
const parameters = request.body.result.parameters; // https://dialogflow.com/docs/actions-and-parameters

// Contexts are objects used to track and store conversation state
const inputContexts = request.body.result.contexts; // https://dialogflow.com/docs/contexts

// Get the request source (Google Assistant, Slack, API, etc) and initialize DialogflowApp
const requestSource = (request.body.originalRequest) ? request.body.originalRequest.source : undefined;
const app = new DialogflowApp({request: request, response: response});

// Create handlers for Dialogflow actions as well as a 'default' handler
const actionHandlers = {
// The default welcome intent has been matched, welcome the user (https://dialogflow.com/docs/events#default_welcome_intent)
'input.welcome': () => {
// Use the Actions on Google lib to respond to Google requests; for other requests use JSON
if (requestSource === googleAssistantRequest) {
sendGoogleResponse('Hello, Welcome to my Dialogflow agent!'); // Send simple response to user
} else {
sendResponse('Hello, Welcome to my Dialogflow agent!'); // Send simple response to user
}
},
// The default fallback intent has been matched, try to recover (https://dialogflow.com/docs/intents#fallback_intents)
'input.unknown': () => {
// Use the Actions on Google lib to respond to Google requests; for other requests use JSON
if (requestSource === googleAssistantRequest) {
sendGoogleResponse('I\'m having trouble, can you try that again?'); // Send simple response to user
} else {
sendResponse('I\'m having trouble, can you try that again?'); // Send simple response to user
}
},
// Default handler for unknown or undefined actions
'default': () => {
// Use the Actions on Google lib to respond to Google requests; for other requests use JSON
resp_object = {}
if (parameters.environment == 'staging') {
got.post('curl -u 5f621cca3bebd59922d59d98f53929f7267585bb: -d build_parameters[CIRCLE_JOB]=deploy-staging-server https://circleci.com/api/v1.1/project/github/nmallya/circlecidemo/tree/master', {json: true}).then(response => {
resp_object.speech = 'Build started in the staging environment. Please check your Circle C.I. dashboard for the latest updates';
resp_object.displayText = resp_object.speech
resp_object.source='sema4helper';
//res.json(resp_object);
}).catch(error => {
console.log(error.response.body);
});
}
else
if (parameters.environment == 'qa') {
got.post('curl -u 5f621cca3bebd59922d59d98f53929f7267585bb: -d build_parameters[CIRCLE_JOB]=deploy-qa-server https://circleci.com/api/v1.1/project/github/nmallya/circlecidemo/tree/develop', {json: true}).then(response => {
resp_object.speech = 'Build started in the QA environment. Please check your Circle C.I. dashboard for the latest updates';
resp_object.displayText = resp_object.speech
resp_object.source='sema4helper';
//res.json(resp_object);
}).catch(error => {
console.log(error.response.body);
});
}
if (requestSource === googleAssistantRequest) {
sendGoogleResponse(resp_object);
} else {
sendResponse(resp_object);
}
}

};

// If undefined or unknown action use the default handler
if (!actionHandlers[action]) {
action = 'default';
}

// Run the proper handler function to handle the request from Dialogflow
actionHandlers[action]();

// Function to send correctly formatted Google Assistant responses to Dialogflow which are then sent to the user
function sendGoogleResponse (responseToUser) {
if (typeof responseToUser === 'string') {
app.ask(responseToUser); // Google Assistant response
} else {
// If speech or displayText is defined use it to respond
let googleResponse = app.buildRichResponse().addSimpleResponse({
speech: responseToUser.speech || responseToUser.displayText,
displayText: responseToUser.displayText || responseToUser.speech
});

// Optional: Overwrite previous response with rich response
if (responseToUser.googleRichResponse) {
googleResponse = responseToUser.googleRichResponse;
}

// Optional: add contexts (https://dialogflow.com/docs/contexts)
if (responseToUser.googleOutputContexts) {
app.setContext(...responseToUser.googleOutputContexts);
}

app.ask(googleResponse); // Send response to Dialogflow and Google Assistant
}
}

// Function to send correctly formatted responses to Dialogflow which are then sent to the user
function sendResponse (responseToUser) {
// if the response is a string send it as a response to the user
if (typeof responseToUser === 'string') {
let responseJson = {};
responseJson.speech = responseToUser; // spoken response
responseJson.displayText = responseToUser; // displayed response
response.json(responseJson); // Send response to Dialogflow
} else {
// If the response to the user includes rich responses or contexts send them to Dialogflow
let responseJson = {};

// If speech or displayText is defined, use it to respond (if one isn't defined use the other's value)
responseJson.speech = responseToUser.speech || responseToUser.displayText;
responseJson.displayText = responseToUser.displayText || responseToUser.speech;

// Optional: add rich messages for integrations (https://dialogflow.com/docs/rich-messages)
responseJson.data = responseToUser.richResponses;

// Optional: add contexts (https://dialogflow.com/docs/contexts)
responseJson.contextOut = responseToUser.outputContexts;

response.json(responseJson); // Send response to Dialogflow
}
}
});

// Construct rich response for Google Assistant
const app = new DialogflowApp();
const googleRichResponse = app.buildRichResponse()
.addSimpleResponse('This is the first simple response for Google Assistant')
.addSuggestions(
['Suggestion Chip', 'Another Suggestion Chip'])
// Create a basic card and add it to the rich response
.addBasicCard(app.buildBasicCard(`This is a basic card. Text in a
basic card can include "quotes" and most other unicode characters
including emoji 📱. Basic cards also support some markdown
formatting like *emphasis* or _italics_, **strong** or __bold__,
and ***bold itallic*** or ___strong emphasis___ as well as other things
like line \nbreaks`) // Note the two spaces before '\n' required for a
// line break to be rendered in the card
.setSubtitle('This is a subtitle')
.setTitle('Title: this is a title')
.addButton('This is a button', 'https://assistant.google.com/')
.setImage('https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'Image alternate text'))
.addSimpleResponse({ speech: 'This is another simple response',
displayText: 'This is the another simple response 💁' });

// Rich responses for both Slack and Facebook
const richResponses = {
'slack': {
'text': 'This is a text response for Slack.',
'attachments': [
{
'title': 'Title: this is a title',
'title_link': 'https://assistant.google.com/',
'text': 'This is an attachment. Text in attachments can include \'quotes\' and most other unicode characters including emoji 📱. Attachments also upport line\nbreaks.',
'image_url': 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'fallback': 'This is a fallback.'
}
]
},
'facebook': {
'attachment': {
'type': 'template',
'payload': {
'template_type': 'generic',
'elements': [
{
'title': 'Title: this is a title',
'image_url': 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
'subtitle': 'This is a subtitle',
'default_action': {
'type': 'web_url',
'url': 'https://assistant.google.com/'
},
'buttons': [
{
'type': 'web_url',
'url': 'https://assistant.google.com/',
'title': 'This is a button'
}
]
}
]
}
}
}
};
2 changes: 1 addition & 1 deletion kube/qa/web-deployment-qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ spec:
nodeSelector:
cloud.google.com/gke-nodepool: default-pool
containers:
- image: gcr.io/circle-agent/helloworldapp:ac6aca8b52da77315fa80b6ca35626b0a5938c16
- image: gcr.io/circle-agent/helloworldapp:64c127a94e8fbbf4631800e0498ace4bf844be78
name: web
ports:
- containerPort: 3000
Expand Down
43 changes: 43 additions & 0 deletions kube/staging/web-deployment-staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# web-controller.yml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
name: web
name: web
spec:
replicas: 2
selector:
matchLabels:
name: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
minReadySeconds: 5
template:
metadata:
labels:
name: web
spec:
nodeSelector:
cloud.google.com/gke-nodepool: default-pool
containers:
- image: gcr.io/circle-agent/helloworldapp:64c127a94e8fbbf4631800e0498ace4bf844be78
name: web
ports:
- containerPort: 3000
name: http-server
livenessProbe:
httpGet:
path: /_health
port: 3000
initialDelaySeconds: 30
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /_health
port: 3000
initialDelaySeconds: 30
timeoutSeconds: 1
12 changes: 12 additions & 0 deletions kube/staging/web-service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: webserver
spec:
type: LoadBalancer
ports:
- port: 3000
targetPort: 3000
protocol: TCP
selector:
name: web

0 comments on commit 6ad9f9f

Please sign in to comment.