Skip to content

Markdown Preview sample #1752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 104 commits into from
Jun 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
9d64ae1
Add service-to-service Node.js sample
Apr 3, 2020
64ab35f
Add service-to-service Node.js sample
kelsk Apr 3, 2020
00451bf
Update run/authentication/auth.js
kelsk Apr 3, 2020
86b0635
Update sample to address suggested changes
kelsk Apr 3, 2020
5132e26
Merge branch 'master' into auth
kelsk Apr 3, 2020
a176376
Merge pull request #1 from kelsk/auth
kelsk Apr 3, 2020
70ce8f7
Merge branch 'master' into master
kelsk Apr 3, 2020
5975b57
Initial code added
kelsk Apr 6, 2020
8e9ef37
Updated package.json; resolved issues in auth.js from review
kelsk Apr 13, 2020
867eb65
Removed auth from branch
kelsk Apr 13, 2020
62fd173
Markdown renderer & editor added
kelsk Apr 20, 2020
02dccb6
Markdown renderer & editor working
kelsk Apr 21, 2020
9ef850f
Added xss sanitizer
kelsk Apr 21, 2020
a56dca4
General cleanup
kelsk Apr 21, 2020
0bafa82
Delete .gitignore
kelsk Apr 21, 2020
bb14175
Delete .gitignore
kelsk Apr 21, 2020
1905b18
Removed errant console.log
kelsk Apr 21, 2020
8353e52
Update markdown converter, general code cleanup
kelsk Apr 23, 2020
039663d
updated README
kelsk Apr 24, 2020
39dfd1f
tests: added unit tests for editor & renderer
kelsk Apr 24, 2020
5985740
added timeout
kelsk Apr 24, 2020
0d0e2ef
tests: added editor & editor/render tests
kelsk Apr 27, 2020
7f32b81
tests: added & modified test in package.json
kelsk Apr 27, 2020
f43a2af
README: added env var
kelsk Apr 27, 2020
2db15ae
Revert "README: added env var"
kelsk Apr 27, 2020
7706dd1
README: added env var
kelsk Apr 27, 2020
0cdf727
updated author email
kelsk Apr 28, 2020
1d17988
Update run/markdown-preview/README.md
kelsk Apr 28, 2020
5fb25b1
add license to Dockerfile
kelsk Apr 29, 2020
43bb924
fixed json parsing error
kelsk Apr 29, 2020
bea221b
remove dependencies from root package.json
kelsk Apr 29, 2020
5277daf
remove xss (not needed)
kelsk Apr 30, 2020
a359786
update node version in Dockerfile
kelsk Apr 30, 2020
4391a1b
refactored code to reflect code review
kelsk Apr 30, 2020
d2410d8
updated tests to respond to new code
kelsk Apr 30, 2020
f2fe58e
update packages.json
kelsk Apr 30, 2020
54649d6
update README: Merge branch 'markdown' of https://github.com/kelsk/no…
kelsk Apr 30, 2020
88dd67d
run/markdown-preview: add sample
kelsk Apr 30, 2020
d70d1a6
update: syntax & grammar fixes
kelsk Apr 30, 2020
a8952fa
change: throw error if markdown data absent from req
kelsk Apr 30, 2020
f2706f0
change req.body validation
kelsk May 1, 2020
bca1bb3
fix syntax error
kelsk May 1, 2020
4890729
change: fixed file name
kelsk May 2, 2020
5de6e9c
syntax: remove newline
kelsk May 5, 2020
c97f02b
update: engine version
kelsk May 5, 2020
6c0897c
syntax: general fixes
kelsk May 5, 2020
8842611
code: replace json with plain text
kelsk May 6, 2020
b81c140
test: modified tests for accuracy
kelsk May 6, 2020
5a1d84e
syntax: minor fixes
kelsk May 6, 2020
971bff9
test: modified for new code
kelsk May 6, 2020
3c4ed75
added comment about xss
kelsk May 6, 2020
f4d8a99
code: unwrapped body.data
kelsk May 7, 2020
330206e
test: updated tests per code review
kelsk May 7, 2020
9f23945
code: added timeout to got request
kelsk May 8, 2020
8a0aa37
test: updated with sinon & error message reading
kelsk May 8, 2020
6bdf2b6
test: updated with sinon to read console log
kelsk May 8, 2020
42c6eb8
reformatted markdown declaration
kelsk May 8, 2020
675b19f
test: refactor to make valid tests
kelsk May 8, 2020
3503649
Updated sample to use google-auth-library
kelsk May 19, 2020
0bbd133
updated req.body conditional & markdown-it comment
kelsk May 19, 2020
d5fff16
Removed init(); added Renderer url to /render
kelsk May 19, 2020
5a7a2ec
Updated renderRequest client
kelsk May 19, 2020
f369ccc
Updated get to be async
kelsk May 19, 2020
394dc63
Updated tests to reflect new code
kelsk May 19, 2020
618b88e
Removed erroneous comment & outdated env var
kelsk May 19, 2020
a7bfaae
Removed unused js package
kelsk May 19, 2020
2b2844c
Added check for service url
kelsk May 19, 2020
eb6bbf1
Updated service url in test/render
kelsk May 19, 2020
a2ca8b5
Updated tests with urls & removed incorrect assertion
kelsk May 19, 2020
13fb1a0
updated POST request test
kelsk May 19, 2020
3084e6f
updated POST request test
kelsk May 19, 2020
829039b
removed 'then' from renderer test
kelsk May 19, 2020
b7a7eaa
test modifications
kelsk May 19, 2020
0a6e84c
Reconfigured serviceUrl
kelsk May 19, 2020
719b304
Removed sinon
kelsk May 21, 2020
5cfb4e6
Updated region tags
kelsk May 21, 2020
59e9e13
Updated valid request test
kelsk May 21, 2020
77d997c
Update: node 10 => node 12
kelsk May 27, 2020
9f9e9bd
Added end to end tests
kelsk Jun 4, 2020
258b7f2
Update run/markdown-preview/editor/test/system.test.js
kelsk Jun 4, 2020
ef89135
Merge branch 'master' into markdown
kelsk Jun 4, 2020
4fbb5f4
Added test to system.test.js
kelsk Jun 4, 2020
b071dfb
Fixed npm test
kelsk Jun 4, 2020
965b1b6
Merge branch 'markdown' of https://github.com/kelsk/nodejs-docs-sampl…
kelsk Jun 4, 2020
6bfc88b
Fixed renderer test
kelsk Jun 4, 2020
0d2d33a
Updated shell permissions
kelsk Jun 4, 2020
4658d62
Updated cleanup func
kelsk Jun 8, 2020
f449c88
Merge branch 'master' into markdown
kelsk Jun 8, 2020
9cc0974
Update var exports
kelsk Jun 8, 2020
f8483e2
Merge branch 'markdown' of https://github.com/kelsk/nodejs-docs-sampl…
kelsk Jun 8, 2020
ef43218
Added service-name.sh
kelsk Jun 9, 2020
ce5ff21
Merge branch 'master' into markdown
averikitsch Jun 9, 2020
0806459
Removed service-name.sh
kelsk Jun 9, 2020
e3b2703
Merge branch 'markdown' of https://github.com/kelsk/nodejs-docs-sampl…
kelsk Jun 9, 2020
bc1b999
Move service.sh functions into runner.sh
kelsk Jun 10, 2020
1a174f0
Merge branch 'master' into markdown
kelsk Jun 10, 2020
71eafed
Added check for BASE_URL
kelsk Jun 10, 2020
45e4ca4
Merge branch 'markdown' of https://github.com/kelsk/nodejs-docs-sampl…
kelsk Jun 10, 2020
9ed8ef5
Fixed system.test env
kelsk Jun 10, 2020
44af029
Add check for BASE_URL var
kelsk Jun 11, 2020
c4a152f
Added id token
kelsk Jun 12, 2020
35e5795
Merge branch 'master' into markdown
kelsk Jun 12, 2020
57aa5ee
Fixed test; removed allow-auth flag
kelsk Jun 12, 2020
9d2028a
Merge branch 'markdown' of https://github.com/kelsk/nodejs-docs-sampl…
kelsk Jun 12, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions run/markdown-preview/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Cloud Run Markdown Preview Sample

[Securing Cloud Run services tutorial](https://cloud.google.com/run/docs/tutorials/secure-services) walks through how to create a secure two-service application running on Cloud Run. This application is a Markdown editor which includes a public "frontend" service which anyone can use to compose Markdown text and a private "backend" service which renders Markdown text to HTML.

For more details on how to work with this sample read the [Google Cloud Run Node.js Samples README](https://github.com/GoogleCloudPlatform/nodejs-docs-samples/tree/master/run).

## Environment Variables

Cloud Run services can be [configured with Environment Variables](https://cloud.google.com/run/docs/configuring/environment-variables).
Required variables for this sample include:

* `EDITOR_UPSTREAM_RENDER_URL`: The URL of the restricted Cloud Run service that
renders Markdown to HTML.

## Dependencies

* **express**: Web server framework.
* **google-auth-library**: OAuth2.0 library for authentication and authorization.
* **got**: Node.js library for HTTP requests.
* **handlebars** JavaScript template engine.
* **markdown-it**: JavaScript library for parsing and rendering Markdown text.
34 changes: 34 additions & 0 deletions run/markdown-preview/editor/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2020 Google LLC
#
# Licensed 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
#
# https://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.

# Use the official lightweight Node.js 10 image.
# https://hub.docker.com/_/node
FROM node:12-slim

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
# Copying this separately prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
RUN npm install --only=production

# Copy local code to the container image.
COPY . ./

# Run the web service on container startup.
CMD [ "npm", "start" ]
70 changes: 70 additions & 0 deletions run/markdown-preview/editor/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2020 Google LLC
//
// Licensed 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
//
// https://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.

const express = require('express');
const handlebars = require('handlebars');
const { readFile } = require('fs').promises;
const renderRequest = require('./render.js');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the reasons why the golang code was structured the way it is: I was hiding from the main flow of the program that the rendering process was an external API call. In fact, from the perspective of two of the files, I could re-implement the rendering to be wholly local and they wouldn't be able to tell.

We don't need to do that in node.js, but it's worth considering how that affects the shape of the code if you aren't trying to abstract things.

For example, should the functions in render.js be included directly in index.js? It's often better to isolate each integration into it's own "space", whether that's called a class, module, file, or something else.


const app = express();
app.use(express.json());

let markdownDefault, compiledTemplate, renderedHtml;

// Load the template files and serve them with the Editor service.
const buildRenderedHtml = async () => {
try {
markdownDefault = await readFile(__dirname + '/templates/markdown.md');
compiledTemplate = handlebars.compile(await readFile(__dirname + '/templates/index.html', 'utf8'));
renderedHtml = compiledTemplate({default: markdownDefault});
return renderedHtml;
} catch(err) {
throw Error ('Error loading template: ', err);
}
};

app.get('/', async (req, res) => {
try {
if (!renderedHtml) renderedHtml = await buildRenderedHtml();
res.status(200).send(renderedHtml);
} catch (err) {
console.log('Error loading the Editor service: ', err);
res.status(500).send(err);
}
});

// The renderRequest makes a request to the Renderer service.
// The request returns the Markdown text converted to HTML.
app.post('/render', async (req, res) => {
try {
const markdown = req.body.data;
const response = await renderRequest(markdown);
res.status(200).send(response);
} catch (err) {
console.log('Error querying the Renderer service: ', err);
res.status(500).send(err);
}
});

const PORT = process.env.PORT || 8080;

app.listen(PORT, err => {
console.log(`Editor service is listening on port ${PORT}`);
});

// Exports for testing purposes.
module.exports = {
app,
buildRenderedHtml
};
31 changes: 31 additions & 0 deletions run/markdown-preview/editor/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "markdown-preview",
"description": "Cloud Run service to demonstrate service-to-service authentication, paired with Renderer service.",
"version": "0.0.1",
"private": true,
"license": "Apache-2.0",
"author": "Google LLC",
"repository": {
"type": "git",
"url": "https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git"
},
"engines": {
"node": ">= 12.0.0"
},
"main": "main.js",
"scripts": {
"e2e-test": "test/runner.sh mocha test/system.test.js --timeout=30000",
"start": "node main.js",
"test": "mocha test/main.test.js test/render.test.js --exit"
},
"dependencies": {
"express": "^4.17.1",
"google-auth-library": "^6.0.0",
"got": "^10.7.0",
"handlebars": "^4.7.6"
},
"devDependencies": {
"mocha": "^7.1.1",
"supertest": "^4.0.2"
}
}
59 changes: 59 additions & 0 deletions run/markdown-preview/editor/render.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright 2020 Google LLC
//
// Licensed 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
//
// https://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.

const {GoogleAuth} = require('google-auth-library');
const got = require('got');
const auth = new GoogleAuth();

let client, serviceUrl;

// renderRequest creates a new HTTP request with IAM ID Token credential.
// This token is automatically handled by private Cloud Run (fully managed) and Cloud Functions.
const renderRequest = async (markdown) => {
// [START run_secure_request]
if (!process.env.EDITOR_UPSTREAM_RENDER_URL) throw Error('EDITOR_UPSTREAM_RENDER_URL needs to be set.');
serviceUrl = process.env.EDITOR_UPSTREAM_RENDER_URL;

// Build the request to the Renderer receiving service.
const serviceRequestOptions = {
method: 'POST',
headers: {
'Content-Type': 'text/plain'
},
body: markdown,
timeout: 3000
};

try {
// Create a Google Auth client with the Renderer service url as the target audience.
if (!client) client = await auth.getIdTokenClient(serviceUrl);
// Fetch the client request headers and add them to the service request headers.
// The client request headers include an ID token that authenticates the request.
const clientHeaders = await client.getRequestHeaders();
serviceRequestOptions.headers['Authorization'] = clientHeaders['Authorization'];
} catch(err) {
throw Error('GoogleAuth server could not respond to request: ', err);
};

try {
// serviceResponse converts the Markdown plaintext to HTML.
const serviceResponse = await got(serviceUrl, serviceRequestOptions);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to call this if the GoogleAuth server could not respond to the request?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to have a second function to make the HTTP request and build/return serviceResponse, and call that function after we make the GoogleAuth request?

Something like:

const renderRequest = async (markdown) => { 
    . . .
    serviceRequestOptions.headers['Authorization'] = clientHeaders['Authorization'];
    getServiceResponse(serviceUrl, serviceRequestHeaders);
  } catch(err) { . . .  };
};

const getServiceResponse = (serviceUrl, serviceRequestHeaders) => {
  try {
    const serviceResponse = await got(serviceUrl, serviceRequestOptions);
    . . .
};

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By my read if something goes wrong with auth the resulting error is thrown. Could you clarify @fhinkel?

return serviceResponse.body;
} catch (err) {
throw Error('Renderer service could not respond to request: ', err);
};
// [END run_secure_request]
};

module.exports = renderRequest;
110 changes: 110 additions & 0 deletions run/markdown-preview/editor/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<!--
Copyright 2020 Google LLC

Licensed 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.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Markdown Editor</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
<link href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css" rel="stylesheet">
<script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body class="mdc-typography">

<header class="mdc-top-app-bar mdc-top-app-bar--fixed">
<div class="mdc-top-app-bar__row">
<section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
<span class="mdc-top-app-bar__title">Markdown Editor</span>
</section>
<section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-end" role="toolbar">
<a href="#code" title="View the code"><i class="material-icons mdc-top-app-bar__action-item mdc-icon-button" aria-hidden="true">code</i></a>
<a href="#tutorial" title="Read the tutorial"><i class="material-icons mdc-top-app-bar__action-item mdc-icon-button" aria-hidden="true">assignment</i></a>
</section>
</div>
</header>

<div role="progressbar" class="mdc-linear-progress mdc-linear-progress--indeterminate mdc-top-app-bar--fixed-adjust" aria-label="Markdown Rendering Progress Bar" aria-valuemin="0" aria-valuemax="1" aria-valuenow="0">
<div class="mdc-linear-progress__bar mdc-linear-progress__primary-bar">
<span class="mdc-linear-progress__bar-inner"></span>
</div>
</div>

<main class="mdc-layout-grid">
<div class="mdc-layout-grid__inner">
<div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-6">
<h2>Markdown Text</h2>
<section class="mdc-card mdc-card--outlined">
<div class="text-field-container">
<div class="mdc-text-field mdc-text-field--fullwidth md-text-field--no-label mdc-text-field--textarea mdc-ripple-upgraded">
<textarea id="editor" class="mdc-text-field__input" style="height: 36rem;">{{ default }}</textarea>
</div></div>

<div class="mdc-card__actions mdc-card__actions--full-bleed">
<button class="editor-button mdc-button mdc-card__action mdc-card__action--button mdc-ripple-surface">
<span class="mdc-button__label">Preview Rendered Markdown</span>
<i class="material-icons" aria-hidden="true">arrow_forward</i>
</button>
</div>
</section></div>

<div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-6">
<h2>Rendered HTML</h2>
<section class="mdc-card mdc-card--outlined">
<div id="preview" style="height: 40rem; padding-left: 10px; padding-right: 10px">Tap "<strong>Preview Rendered Markdown</strong>" below the text entry to see rendered content.</div>
</section></div>
</div>
</div>
</main>

<script>
const preview = document.getElementById('preview');
const lp = new mdc.linearProgress.MDCLinearProgress(document.querySelector('.mdc-linear-progress'));
async function render(data = {}) {
const response = await fetch('/render', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});

const text = await response.text();
if (!response.ok) {
console.log('error: Render Text: Received status code: ' + response.status);
}

return text;
}

function listener() {
lp.open();
render({data: document.getElementById('editor').value})
.then((result) => preview.innerHTML = result)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we mixing awai and then in one file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@grayside thoughts on updating this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should fix this to use await wherever possible and backtrack to the other languages.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should fix this to use await wherever possible and backtrack to the other languages.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should fix this to use await wherever possible and backtrack to the other languages.

.catch((err) => {
console.log('Render Text: ' + err.message);
preview.innerHTML = '<h3><i aria-hidden="true" class="material-icons">error</i>Render Error</h3>\n<p>' + err.message + '</p>';
})
.finally(() => lp.close())
}

document.querySelector('.editor-button').addEventListener('click', listener);
window.addEventListener('load', listener);
</script>
</body>
</html>

19 changes: 19 additions & 0 deletions run/markdown-preview/editor/templates/markdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Playing with Markdown

This UI allows a user to write Markdown text and preview the rendered HTML.

You may be familiar with this workflow from sites such as Github or Wikipedia.

In practice, this web page does the following:

* On click of the *"Preview Rendered Markdown"* button, browser JavaScript
lifts the markdown text and sends it to the editor UI's public backend.
* The editor backend sends the text to a private Renderer service which
converts it to HTML.
* The HTML is injected into the web page in the right-side **Rendered HTML** area.

## Markdown Background

Markdown is a text-to-HTML conversion tool that allows you to convert plain text to valid HTML.

Read more about the [syntax on Wikipedia](https://en.wikipedia.org/wiki/Markdown).
38 changes: 38 additions & 0 deletions run/markdown-preview/editor/test/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env bash

# Copyright 2020 Google LLC.
#
# Licensed 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.

set -eo pipefail;

requireEnv() {
test "${!1}" || (echo "Environment Variable '$1' not found" && exit 1)
}

requireEnv SERVICE_NAME
requireEnv CONTAINER_IMAGE

# Deploy the service
set -x
gcloud run deploy "${SERVICE_NAME}" \
--image="${CONTAINER_IMAGE}" \
--region="${REGION:-us-central1}" \
${FLAGS} \
--platform=managed \
--quiet
set +x

echo 'Cloud Run Links:'
echo "- Logs: https://console.cloud.google.com/logs/viewer?project=${GOOGLE_CLOUD_PROJECT}&resource=cloud_run_revision%2Fservice_name%2F${SERVICE_NAME}"
echo "- Console: https://console.cloud.google.com/run/detail/${REGION:-us-central1}/${SERVICE_NAME}/metrics?project=${GOOGLE_CLOUD_PROJECT}"
Loading