Skip to content

Commit

Permalink
Merge pull request #183 from zugdev/kv-binding-in-actions
Browse files Browse the repository at this point in the history
chore: pull kv workflow into testing branches to execute
  • Loading branch information
zugdev authored Dec 13, 2024
2 parents cfc9af2 + a7a84ab commit 4c675e0
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .dev.vars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
WEBHOOK_PROXY_URL=https://smee.io/new
APP_WEBHOOK_SECRET=xxxxxx
APP_ID=123456
ENVIRONMENT=development | production
34 changes: 33 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,43 @@ on:
types:
- completed

permissions:
contents: read

jobs:
deploy-to-cloudflare:
name: Automatic Cloudflare Deploy
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20.10.0

- name: Run setup script
run: |
yarn install
yarn setup-kv
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

- name: Update wrangler.toml Name Field
run: |
branch_name=$(echo '${{ github.event.ref }}' | sed 's#refs/heads/##' | sed 's#[^a-zA-Z0-9]#-#g')
# Extract base name from wrangler.toml
base_name=$(grep '^name = ' wrangler.toml | sed 's/^name = "\(.*\)"$/\1/')
# Concatenate branch name with base name
new_name="${base_name}-${branch_name}"
# Truncate the new name to 63 characters for RFC 1035
new_name=$(echo "$new_name" | cut -c 1-63)
# Update the wrangler.toml file
sed -i "s/^name = .*/name = \"$new_name\"/" wrangler.toml
echo "Updated wrangler.toml name to: $new_name"
- name: Deploy to Cloudflare
if: ${{ github.event.workflow_run.conclusion == 'success' }}
uses: ubiquity/cloudflare-deploy-action@main
Expand All @@ -26,4 +58,4 @@ jobs:
commit_sha: ${{ github.event.workflow_run.head_sha }}
workflow_run_id: ${{ github.event.workflow_run.id }}
app_id: ${{ secrets.APP_ID }}
app_private_key: ${{ secrets.APP_PRIVATE_KEY }}
app_private_key: ${{ secrets.APP_PRIVATE_KEY }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ node_modules
.pnp.loader.mjs
static/dist
.env
.dev.vars
.wrangler/

cypress/screenshots
Expand Down
108 changes: 108 additions & 0 deletions deploy/setup-kv-namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// This file is a fork from: https://github.com/ubiquity-os/ubiquity-os-kernel

/**
* The purpose of the script is to ensure that the KV for the worker is properly set on deployment.
* There is currently a bug that makes the environment reset on each deploy, because of a problem with Wrangler not
* parsing the TOML configuration properly. See https://github.com/cloudflare/workers-sdk/issues/5634
* It seems to only work when the values are set at the root of the TOML, not withing the environments.
* This scripts takes out the Production values for kv_namespaces and rewrites them at the root of the TOML file.
*/

import { execSync } from "child_process";
import * as fs from "fs";
import * as toml from "toml";
// @ts-expect-error No typings exist for this package
import * as tomlify from "tomlify-j0.4";

const tomlFilePath = "./wrangler.toml";
const wranglerToml: WranglerConfiguration = toml.parse(fs.readFileSync(tomlFilePath, "utf-8"));

const NAMESPACE_TITLE = "kv";
const NAMESPACE_TITLE_WITH_PREFIX = `${wranglerToml.name}-${NAMESPACE_TITLE}`;
const BINDING_NAME = "REFERRAL_TRACKING";

interface Namespace {
id: string;
title: string;
}

interface WranglerConfiguration {
name: string;
env: {
production: {
kv_namespaces?: {
id: string;
binding: string;
}[];
};
dev: {
kv_namespaces?: {
id: string;
binding: string;
}[];
};
};
kv_namespaces: {
id: string;
binding: string;
}[];
}

function updateWranglerToml(namespaceId: string) {
// Ensure kv_namespaces array exists
if (!wranglerToml.kv_namespaces) {
wranglerToml.kv_namespaces = [];
}
if (wranglerToml.env.production.kv_namespaces) {
wranglerToml.kv_namespaces = wranglerToml.env.production.kv_namespaces;
delete wranglerToml.env.production.kv_namespaces;
}
if (wranglerToml.env.dev.kv_namespaces) {
delete wranglerToml.env.dev.kv_namespaces;
}

const existingNamespace = wranglerToml.kv_namespaces.find((o) => o.binding === BINDING_NAME);
if (existingNamespace) {
existingNamespace.id = namespaceId;
} else {
wranglerToml.kv_namespaces.push({
binding: BINDING_NAME,
id: namespaceId,
});
}

fs.writeFileSync(tomlFilePath, tomlify.toToml(wranglerToml, { space: 1 }));
}

async function main() {
// Check if the namespace exists or create a new one
let namespaceId: string;
try {
const res = execSync(`wrangler kv namespace create ${NAMESPACE_TITLE}`).toString();
console.log(res);
const newId = res.match(/id = \s*"([^"]+)"/)?.[1];
if (!newId) {
throw new Error(`The new ID could not be found.`);
}
namespaceId = newId;
console.log(`Namespace created with ID: ${namespaceId}`);
} catch (error) {
console.error(error);
const listOutput = JSON.parse(execSync(`wrangler kv namespace list`).toString()) as Namespace[];
const existingNamespace = listOutput.find((o) => o.title === NAMESPACE_TITLE_WITH_PREFIX);
if (!existingNamespace) {
throw new Error(`Error creating namespace: ${error}`);
}
namespaceId = existingNamespace.id;
console.log(`Namespace ${NAMESPACE_TITLE_WITH_PREFIX} already exists with ID: ${namespaceId}`);
}

updateWranglerToml(namespaceId);
}

main()
.then(() => console.log("Successfully bound namespace."))
.catch((e) => {
console.error("Error checking or creating namespace:\n", e);
process.exit(1);
});
10 changes: 5 additions & 5 deletions functions/referral-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async function handleSet(env: Env, request: Request): Promise<Response> {

const { gitHubUserId, referralCode } = result;

const oldRefCode = await env.KVNamespace.get(gitHubUserId);
const oldRefCode = await env.REFERRAL_TRACKING.get(gitHubUserId);

if (oldRefCode) {
return new Response(`Key '${gitHubUserId}' already has a referral code: '${oldRefCode}'`, {
Expand All @@ -68,7 +68,7 @@ async function handleSet(env: Env, request: Request): Promise<Response> {
});
}

await env.KVNamespace.put(gitHubUserId, referralCode);
await env.REFERRAL_TRACKING.put(gitHubUserId, referralCode);

return new Response(`Key '${gitHubUserId}' added with value '${referralCode}'`, {
headers: corsHeaders,
Expand All @@ -77,7 +77,7 @@ async function handleSet(env: Env, request: Request): Promise<Response> {
}

async function handleGet(gitHubUserId: string, env: Env): Promise<Response> {
const referralCode = await env.KVNamespace.get(gitHubUserId);
const referralCode = await env.REFERRAL_TRACKING.get(gitHubUserId);
if (referralCode) {
return new Response(`Value for '${gitHubUserId}': ${referralCode}`, {
headers: corsHeaders,
Expand All @@ -92,11 +92,11 @@ async function handleGet(gitHubUserId: string, env: Env): Promise<Response> {
}

async function handleList(env: Env): Promise<Response> {
const gitHubUsersIds = await env.KVNamespace.list();
const gitHubUsersIds = await env.REFERRAL_TRACKING.list();
const referrals: Record<string, string | null> = {};

for (const { name: userId } of gitHubUsersIds.keys) {
const referralCode = await env.KVNamespace.get(userId);
const referralCode = await env.REFERRAL_TRACKING.get(userId);
referrals[userId] = referralCode;
}

Expand Down
2 changes: 1 addition & 1 deletion functions/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EventContext, KVNamespace } from "@cloudflare/workers-types";

export interface Env {
KVNamespace: KVNamespace;
REFERRAL_TRACKING: KVNamespace;
}

export interface POSTRequestBody {
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"prepare": "husky install",
"test": "jest --setupFiles dotenv/config --coverage",
"cy:open": "cypress open",
"cy:run": "cypress run"
"cy:run": "cypress run",
"setup-kv": "tsx --env-file=.dev.vars deploy/setup-kv-namespace.ts"
},
"keywords": [
"typescript",
Expand Down Expand Up @@ -57,6 +58,8 @@
"lint-staged": "^15.1.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.5",
"toml": "3.0.0",
"tomlify-j0.4": "3.0.0",
"ts-jest": "29.1.2",
"tsx": "^4.7.1",
"typescript": "^5.3.3"
Expand Down
8 changes: 1 addition & 7 deletions src/home/fetch-github/fetch-and-display-previews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,7 @@ export async function displayGitHubIssues({
applyAvatarsToIssues();
}

export async function searchDisplayGitHubIssues({
searchText,
skipAnimation = false,
}: {
searchText: string;
skipAnimation?: boolean;
}) {
export async function searchDisplayGitHubIssues({ searchText, skipAnimation = false }: { searchText: string; skipAnimation?: boolean }) {
const searchResult = filterIssuesBySearch(searchText);
let filteredIssues = searchResult.filter(getProposalsOnlyFilter(isProposalOnlyViewer));
filteredIssues = filterIssuesByOrganization(filteredIssues);
Expand Down
16 changes: 6 additions & 10 deletions src/home/search/string-similarity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,23 @@ export class StringSimilarity {
public static calculate(str1: string, str2: string): number {
const maxLen = Math.max(str1.length, str2.length);
if (maxLen === 0) return 1.0;

const distance = this._calculateLevenshteinDistance(str1, str2);
return 1 - (distance / maxLen);
return 1 - distance / maxLen;
}

private static _calculateLevenshteinDistance(str1: string, str2: string): number {
const matrix: number[][] = Array(str2.length + 1).fill(null).map(() =>
Array(str1.length + 1).fill(null)
);
const matrix: number[][] = Array(str2.length + 1)
.fill(null)
.map(() => Array(str1.length + 1).fill(null));

for (let i = 0; i <= str1.length; i++) matrix[0][i] = i;
for (let j = 0; j <= str2.length; j++) matrix[j][0] = j;

for (let j = 1; j <= str2.length; j++) {
for (let i = 1; i <= str1.length; i++) {
const indicator = str1[i - 1] === str2[j - 1] ? 0 : 1;
matrix[j][i] = Math.min(
matrix[j][i - 1] + 1,
matrix[j - 1][i] + 1,
matrix[j - 1][i - 1] + indicator
);
matrix[j][i] = Math.min(matrix[j][i - 1] + 1, matrix[j - 1][i] + 1, matrix[j - 1][i - 1] + indicator);
}
}

Expand Down
11 changes: 1 addition & 10 deletions wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,5 @@ compatibility_date = "2024-10-23"

pages_build_output_dir = "./static"

[[kv_namespaces]]
binding = "KVNamespace"
id = "0a6aaf0a6edb428189606b116da58ef7"

[vars]
YARN_VERSION = "1.22.22"

# These secrets need to be configured via Cloudflare dashboard:
# SUPABASE_URL = ""
# SUPABASE_ANON_KEY = ""

YARN_VERSION = "1.22.22"
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1771,6 +1771,8 @@ __metadata:
marked: "npm:^11.0.0"
npm-run-all: "npm:^4.1.5"
prettier: "npm:^3.2.5"
toml: "npm:3.0.0"
tomlify-j0.4: "npm:3.0.0"
ts-jest: "npm:29.1.2"
tsx: "npm:^4.7.1"
typescript: "npm:^5.3.3"
Expand Down Expand Up @@ -7538,6 +7540,20 @@ __metadata:
languageName: node
linkType: hard

"toml@npm:3.0.0":
version: 3.0.0
resolution: "toml@npm:3.0.0"
checksum: 8d7ed3e700ca602e5419fca343e1c595eb7aa177745141f0761a5b20874b58ee5c878cd045c408da9d130cb2b611c639912210ba96ce2f78e443569aa8060c18
languageName: node
linkType: hard

"tomlify-j0.4@npm:3.0.0":
version: 3.0.0
resolution: "tomlify-j0.4@npm:3.0.0"
checksum: 78349675ac24e4aa7b518f54cb3b55884d9f5d5a6a44fdeff63b3c55887ccce7c491802f2a527ee38a559d259adc5a14b431f926f892179f020db3d5025d9a94
languageName: node
linkType: hard

"tough-cookie@npm:^5.0.0":
version: 5.0.0
resolution: "tough-cookie@npm:5.0.0"
Expand Down

1 comment on commit 4c675e0

@ubiquity-os
Copy link
Contributor

@ubiquity-os ubiquity-os bot commented on 4c675e0 Dec 13, 2024

Choose a reason for hiding this comment

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

@zugdev Configuration is invalid.

Caution

- plugin: https://ubiquibot-command-wallet-development.ubiquity.workers.dev

path: plugins/0/uses/0
value: "https://ubiquibot-command-wallet-development.ubiquity.workers.dev"
message: Failed to fetch the manifest configuration.

Caution

- plugin: https://ubiquibot-command-query-user-development.ubiquity.workers.dev

path: plugins/1/uses/0
value: "https://ubiquibot-command-query-user-development.ubiquity.workers.dev"
message: Failed to fetch the manifest configuration.

Please sign in to comment.