Skip to content

Commit

Permalink
Support jobs metadata too (#519)
Browse files Browse the repository at this point in the history
Closes
#508
  • Loading branch information
sethvargo authored May 10, 2024
1 parent 1b14a74 commit a6ebc7d
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 76 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ jobs:
- name: 'Set service name in metadata YAML'
run: |-
sed -i "s/run-full-yaml/${{ env.SERVICE_NAME }}/" ./tests/unit/service.yaml
sed -i "s/run-full-yaml/${{ env.SERVICE_NAME }}/" ./tests/fixtures/service.yaml
- uses: 'actions/setup-node@v4'
with:
Expand All @@ -180,7 +180,7 @@ jobs:
name: 'Deploy'
uses: './'
with:
metadata: './tests/unit/service.yaml'
metadata: './tests/fixtures/service.yaml'

- name: 'Run initial deploy tests'
run: 'npm run e2e-tests'
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ jobs:
### Custom metadata YAML

For advanced use cases, you can define a custom Cloud Run metadata file. This is
a YAML description of the Cloud Run service. This allows you to customize your
a YAML description of the Cloud Run service or job. This allows you to customize your
service configuration, such as [memory
limits](https://cloud.google.com/run/docs/configuring/memory-limits), [CPU
allocation](https://cloud.google.com/run/docs/configuring/cpu), [max
Expand All @@ -271,7 +271,7 @@ instances](https://cloud.google.com/run/docs/configuring/max-instances), and

**⚠️ When using a custom metadata YAML file, all other inputs are ignored!**

- `metadata`: (Optional) The path to a Cloud Run service metadata file.
- `metadata`: (Optional) The path to a Cloud Run service or job metadata file.

To [deploying a new service](https://cloud.google.com/run/docs/deploying#yaml)
to create a new YAML service definition:
Expand Down
27 changes: 14 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"@actions/exec": "^1.1.1",
"@actions/tool-cache": "^2.0.1",
"@google-github-actions/actions-utils": "^0.7.5",
"@google-github-actions/setup-cloud-sdk": "^1.1.6"
"@google-github-actions/setup-cloud-sdk": "^1.1.6",
"yaml": "^2.4.2"
},
"devDependencies": {
"@types/node": "^20.12.11",
Expand Down
70 changes: 21 additions & 49 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import {
} from '@actions/core';
import { getExecOutput } from '@actions/exec';
import * as toolCache from '@actions/tool-cache';
import { readFile } from 'fs/promises';
import { parse as parseYAML } from 'yaml';

import {
errorMessage,
isPinnedToHead,
Expand Down Expand Up @@ -146,45 +149,17 @@ export async function run(): Promise<void> {
cmd = ['run', 'services', 'update-traffic', service];
if (revTraffic) cmd.push('--to-revisions', revTraffic);
if (tagTraffic) cmd.push('--to-tags', tagTraffic);

const providedButIgnored: Record<string, boolean> = {
image: image !== '',
metadata: metadata !== '',
source: source !== '',
env_vars: envVars !== '',
no_traffic: noTraffic,
secrets: Object.keys(secrets).length > 0,
suffix: suffix !== '',
tag: tag !== '',
labels: Object.keys(labels).length > 0,
timeout: timeout !== '',
};
for (const key in providedButIgnored) {
if (providedButIgnored[key]) {
logWarning(`Updating traffic, ignoring "${key}" input`);
}
}
} else if (metadata) {
cmd = ['run', 'services', 'replace', metadata];

const providedButIgnored: Record<string, boolean> = {
image: image !== '',
service: service !== '',
source: source !== '',
env_vars: envVars !== '',
no_traffic: noTraffic,
secrets: Object.keys(secrets).length > 0,
suffix: suffix !== '',
tag: tag !== '',
revision_traffic: revTraffic !== '',
tag_traffic: revTraffic !== '',
labels: Object.keys(labels).length > 0,
timeout: timeout !== '',
};
for (const key in providedButIgnored) {
if (providedButIgnored[key]) {
logWarning(`Using metadata YAML, ignoring "${key}" input`);
}
const contents = await readFile(metadata, 'utf8');
const parsed = parseYAML(contents);

const kind = parsed?.kind;
if (kind === 'Service') {
cmd = ['run', 'services', 'replace', metadata];
} else if (kind === 'Job') {
cmd = ['run', 'jobs', 'replace', metadata];
} else {
throw new Error(`Unkown metadata type "${kind}", expected "Job" or "Service"`);
}
} else if (job) {
logWarning(
Expand Down Expand Up @@ -249,17 +224,14 @@ export async function run(): Promise<void> {

// Push common flags
cmd.push('--format', 'json');
if (region) {
switch (region.length) {
case 0:
break;
case 1:
cmd.push('--region', region[0]);
break;
default:
cmd.push('--region', region.join(','));
break;
}
if (region?.length > 0) {
cmd.push(
'--region',
region
.flat()
.filter((e) => e !== undefined && e !== null && e !== '')
.join(','),
);
}
if (projectId) cmd.push('--project', projectId);

Expand Down
25 changes: 25 additions & 0 deletions tests/fixtures/job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: 'run.googleapis.com/v1'
kind: 'Job'
metadata:
name: 'job'
labels:
cloud.googleapis.com/location: 'us-east1'
spec:
template:
metadata:
annotations:
run.googleapis.com/execution-environment: 'gen2'
spec:
parallelism: 1
taskCount: 1
template:
spec:
containers:
- image: 'gcr.io/cloudrun/hello'
imagePullPolicy: 'Always'
resources:
limits:
cpu: '1000m'
memory: '512Mi'
maxRetries: 0
timeoutSeconds: '3600'
12 changes: 6 additions & 6 deletions tests/unit/service.yaml → tests/fixtures/service.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
apiVersion: serving.knative.dev/v1
kind: Service
apiVersion: 'serving.knative.dev/v1'
kind: 'Service'
metadata:
name: run-full-yaml
name: 'run-full-yaml'
spec:
template:
metadata:
labels:
test_label: test_value
test_label: 'test_value'
annotations:
run.googleapis.com/cloudsql-instances: 'test-project:us-central1:my-test-instance'
spec:
containerConcurrency: 20
containers:
- image: gcr.io/cloudrun/hello
- image: 'gcr.io/cloudrun/hello'
ports:
- containerPort: 8080
resources:
limits:
cpu: '2'
memory: 1Gi
memory: '1Gi'
timeoutSeconds: 300
18 changes: 15 additions & 3 deletions tests/unit/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,28 @@ test('#run', { concurrency: true }, async (suite) => {
assertMembers(args, ['--source', 'example-app']);
});

await suite.test('sets metadata if given', async (t) => {
await suite.test('sets service metadata if given', async (t) => {
const mocks = defaultMocks(t.mock, {
metadata: 'yaml',
metadata: 'tests/fixtures/service.yaml',
image: '',
});

await run();

const args = mocks.getExecOutput.mock.calls?.at(0).arguments?.at(1);
assertMembers(args, ['services', 'replace', 'yaml']);
assertMembers(args, ['services', 'replace']);
});

await suite.test('sets job metadata if given', async (t) => {
const mocks = defaultMocks(t.mock, {
metadata: 'tests/fixtures/job.yaml',
image: '',
});

await run();

const args = mocks.getExecOutput.mock.calls?.at(0).arguments?.at(1);
assertMembers(args, ['jobs', 'replace']);
});

await suite.test('sets timeout if given', async (t) => {
Expand Down

0 comments on commit a6ebc7d

Please sign in to comment.