Skip to content

Commit

Permalink
fix: restore worker settings (#712)
Browse files Browse the repository at this point in the history
* fix: allow edge arch alone

* fix: restore cf worker settings after deploy

* chore: cleanup
  • Loading branch information
maxakuru authored Jun 10, 2024
1 parent 5a13f74 commit 8ba9ca1
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 3 deletions.
6 changes: 5 additions & 1 deletion src/bundler/BaseBundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,10 @@ export default class BaseBundler {

async updateArchive(archive, packageJson) {
const { cfg } = this;
archive.file(cfg.bundle, { name: 'index.js' });
if (cfg.archs.includes('node')) {
archive.file(cfg.bundle, { name: 'index.js' });
}

cfg.statics.forEach(([src, name]) => {
try {
if (fse.lstatSync(src)
Expand All @@ -168,6 +171,7 @@ export default class BaseBundler {
throw Error(`error with static file: ${e.message}`);
}
});

cfg.modules.forEach((mod) => {
archive.directory(path.resolve(cfg.cwd, `node_modules/${mod}`), `node_modules/${mod}`);
});
Expand Down
5 changes: 5 additions & 0 deletions src/bundler/EdgeBundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,9 @@ export default class EdgeBundler extends WebpackBundler {
}
return this.createWebpackBundle('edge');
}

// eslint-disable-next-line class-methods-use-this
validateBundle() {
// TODO: validate edge bundle, skipped since we're on node
}
}
7 changes: 6 additions & 1 deletion src/deploy/CloudflareConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ export default class CloudflareConfig {

static yarg(yargs) {
return yargs
.group(['cloudflare-account-id', 'cloudflare-auth', 'cloudflare-email', 'cloudflare-test-domain'], 'Cloudflare Workers Deployment Options')
.group([
'cloudflare-account-id',
'cloudflare-auth',
'cloudflare-email',
'cloudflare-test-domain',
], 'Cloudflare Workers Deployment Options')
.option('cloudflare-account-id', {
description: 'the Cloudflare account ID to deploy to',
type: 'string',
Expand Down
35 changes: 35 additions & 0 deletions src/deploy/CloudflareDeployer.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default class CloudflareDeployer extends BaseDeployer {

async deploy() {
const body = fs.readFileSync(this.cfg.edgeBundle);
const settings = await this.getSettings();
const { id } = await this.createKVNamespace(`${this.cfg.packageName}--secrets`);

const metadata = {
Expand Down Expand Up @@ -86,12 +87,46 @@ export default class CloudflareDeployer extends BaseDeployer {
}

await this.updatePackageParams(id, this.cfg.packageParams);

await this.restoreSettings(settings);
}

async getSettings() {
const res = await this.fetch(`https://api.cloudflare.com/client/v4/accounts/${this._cfg.accountID}/workers/scripts/${this.fullFunctionName}/script-settings`, {
method: 'GET',
headers: {
Authorization: `Bearer ${this._cfg.auth}`,
},
});
if (!res.ok) {
return null;
}
const { result } = await res.json();
return result;
}

async restoreSettings(existing) {
if (!existing) {
return true;
}
const res = await this.fetch(`https://api.cloudflare.com/client/v4/accounts/${this._cfg.accountID}/workers/scripts/${this.fullFunctionName}/script-settings`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${this._cfg.auth}`,
'content-type': 'application/json',
},
body: JSON.stringify(existing),
});
return res.ok;
}

async updatePackageParams(id, params) {
const kvlist = Object.entries(params).map(([key, value]) => ({
key, value,
}));
if (!kvlist.length) {
return true;
}

const res = await this.fetch(`https://api.cloudflare.com/client/v4/accounts/${this._cfg.accountID}/storage/kv/namespaces/${id}/bulk`, {
method: 'PUT',
Expand Down
2 changes: 1 addition & 1 deletion src/template/validate-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ async function run(bundlePath, cfg) {
},
},
};

const testUrl = String(test).startsWith('/') ? test : cfg.testUrl;
if (testUrl) {
const url = new URL(testUrl, 'https://localhost/');
event.pathParameters.path = url.pathname.substring(1);
event.rawPath += url.pathname;
event.rawQueryString = url.searchParams.toString();
}

const fn = typeof lambda.raw === 'function' ? lambda.raw : lambda;
result.response = await fn(event, {
invokedFunctionArn: `arn:aws:lambda:us-east-1:118435662149:function:${cfg.packageName}--${cfg.baseName}:${cfg.version}`,
Expand Down
115 changes: 115 additions & 0 deletions test/deploy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,121 @@ describe('Deploy Test', () => {
assert.ok(out.indexOf('$ curl "https://example.com/api/v1/web/foobar/test-package/simple-project"') > 0);
}).timeout(15000);

it('deploys a cloudflare worker on edge arch alone', async () => {
await fse.copy(path.resolve(__rootdir, 'test', 'fixtures', 'cf-worker'), testRoot);

let body;
nock('https://api.cloudflare.com')
.get('/client/v4/accounts/123/workers/scripts/default--test-worker/script-settings')
.reply(404)
.post('/client/v4/accounts/123/storage/kv/namespaces', (b) => {
body = b;
return true;
})
.reply(200, JSON.stringify({ result: { id: 'test-namespace' } }))
.put('/client/v4/accounts/123/workers/scripts/default--test-worker')
.reply(200);

process.chdir(testRoot); // need to change .cwd() for yargs to pickup `wsk` in package.json
const builder = new CLI()
.prepare([
'--build',
'--target', 'cloudflare',
'--arch', 'edge',
'--verbose',
'--deploy',
'--entryFile', 'index.js',
'--directory', testRoot,
'--cloudflare-email', 'fake@email.test',
'--cloudflare-account-id', '123',
'--cloudflare-auth', 'test-token',
'--name', 'test-worker',
]);
builder.cfg._logger = new TestLogger();

const res = await builder.run();

assert.deepEqual(body, { title: 'default--secrets' });

assert.deepEqual(res, {
cloudflare: {
name: 'cloudflare;host=https://null',
url: 'default--test-worker',
},
});
}).timeout(15000);

it('deploys a cloudflare worker and restores existing script settings', async () => {
await fse.copy(path.resolve(__rootdir, 'test', 'fixtures', 'cf-worker'), testRoot);

const bodies = { namespaces: undefined, settings: undefined };
nock('https://api.cloudflare.com')
.get('/client/v4/accounts/123/workers/scripts/default--test-worker/script-settings')
.reply(200, JSON.stringify({
success: true,
result: {
logpush: true,
tail_consumers: [
{
environment: 'production',
namespace: 'my-namespace',
service: 'my-log-consumer',
},
],
},
}))
.post('/client/v4/accounts/123/storage/kv/namespaces', (b) => {
bodies.namespaces = b;
return true;
})
.reply(200, JSON.stringify({ result: { id: 'test-namespace' } }))
.put('/client/v4/accounts/123/workers/scripts/default--test-worker')
.reply(200)
.patch('/client/v4/accounts/123/workers/scripts/default--test-worker/script-settings', (b) => {
bodies.settings = b;
return true;
})
.reply(200);

process.chdir(testRoot); // need to change .cwd() for yargs to pickup `wsk` in package.json
const builder = new CLI()
.prepare([
'--build',
'--target', 'cloudflare',
'--arch', 'edge',
'--verbose',
'--deploy',
'--entryFile', 'index.js',
'--directory', testRoot,
'--cloudflare-email', 'fake@email.test',
'--cloudflare-account-id', '123',
'--cloudflare-auth', 'test-token',
'--name', 'test-worker',
]);
builder.cfg._logger = new TestLogger();

const res = await builder.run();

assert.deepEqual(bodies.namespaces, { title: 'default--secrets' });
assert.deepEqual(bodies.settings, {
logpush: true,
tail_consumers: [
{
environment: 'production',
namespace: 'my-namespace',
service: 'my-log-consumer',
},
],
});

assert.deepEqual(res, {
cloudflare: {
name: 'cloudflare;host=https://null',
url: 'default--test-worker',
},
});
}).timeout(15000);

it.skip('deploys a pure action', async () => {
await fse.copy(path.resolve(__rootdir, 'test', 'fixtures', 'pure-action'), testRoot);

Expand Down
16 changes: 16 additions & 0 deletions test/fixtures/cf-worker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright 2019 Adobe. All rights reserved.
* This file is licensed 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 REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import { Response } from '@adobe/fetch';

export function main() {
return new Response('hello, world', { status: 200 });
}
12 changes: 12 additions & 0 deletions test/fixtures/cf-worker/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "cf-worker-esm",
"version": "1.45.0",
"description": "Cloudflare worker Test Project",
"private": true,
"license": "Apache-2.0",
"main": "index.js",
"type": "module",
"dependencies": {
"@adobe/fetch": "3.1.4"
}
}

0 comments on commit 8ba9ca1

Please sign in to comment.