Skip to content

Commit 4d60f45

Browse files
feat: use turso as main data source (#414)
* feat: scafold for jenkinsfile * feat: turso and bff done * feat: update node ver * fix: branching * fix: typo * fix: jenkins file * fix: wrangler deploy precnt * fix: jenkins file * fix: parsing output * feat: deploying pages * fix: too long db name * build: install valibot drizzle orm and libsql * feat: add turso middleware * feat: add drizzle utils * refactor: replace zod with valibot * feat: add schema * refactor: use turso in articles api * refactor: use turso in authors api * refactor: replace zod with valibot in newsletter api * build: remove zod * refactor: bff cleanup * refactor: use api v2 * refactor: adjust client to new bff with turso * fix: fix jenkins file * feat: replace illgal chars in db name * feat: changes secrets to json file * feat: get proper id with secrets * fix: fix gettting proper version and url * fix: add publishDate to article list contract * feat: comments or pr-s, detecting pr-s * fix: parentheese matching * fix: lack of step * fix: using env var before checking * fix: db branch name lower case * fix; commeting on pr * fix: fix formating * feat: commenting on failed * fix: lang import * review fixed * add prting output for commands * fix bad upload * fix: rollback banner mock * add wp env, change branchs names * test * test * test * test sleep 10 * update wrangler * update wrangler * update wrangler * refactor(bff): remove cache from banners api * test * test * add logs * moar logs * temp fix banners * added cleaning old db branches * fix * fix * turned dryrun to false * change email validation * replace banners api url --------- Co-authored-by: Dominik Donoch <[email protected]>
1 parent b78d51b commit 4d60f45

File tree

50 files changed

+1469
-458
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1469
-458
lines changed

.eslintrc.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,14 @@
6363
"onlyDependOnLibsWithTags": [
6464
"type:api",
6565
"type:contract",
66-
"type:util"
66+
"type:util",
67+
"type:schema"
6768
]
6869
},
70+
{
71+
"sourceTag": "type:schema",
72+
"onlyDependOnLibsWithTags": ["type:types", "type:contract"]
73+
},
6974
{
7075
"sourceTag": "type:util",
7176
"onlyDependOnLibsWithTags": ["type:util", "type:contract"]

Dockerfile-deploy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ENV PATH="/usr/local/go/bin:${PATH}"
1010
RUN mkdir -p /go
1111
ENV GOPATH="/go"
1212
ENV PATH="/go/bin:$PATH"
13-
RUN go install github.com/tursodatabase/turso-cli/cmd/turso@latest
13+
RUN go install github.com/tursodatabase/turso-cli/cmd/turso@v1.0.3
1414

1515
COPY . /app
1616
WORKDIR /app

Jenkinsfile.deploy

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
pipeline {
2+
agent {
3+
dockerfile {
4+
filename 'Dockerfile-deploy'
5+
reuseNode true
6+
}
7+
}
8+
9+
options {
10+
quietPeriod(0)
11+
disableConcurrentBuilds()
12+
timestamps()
13+
}
14+
15+
environment {
16+
KV_DEV = credentials('cf-kv-dev')
17+
KV_PROD = credentials('cf-kv-prod')
18+
AL_BASE_URL = 'https://angular.love'
19+
TURSO_ORG="angular-love"
20+
TURSO_EU_DB=credentials('turso-eu-db')
21+
TURSO_US_WEST_DB=credentials('turso-us-west-db')
22+
TURSO_US_EAST_DB=credentials('turso-us-east-db')
23+
TURSO_EU_AUTH_TOKEN=credentials('turso-eu-auth-token')
24+
TURSO_US_WEST_AUTH_TOKEN=credentials('turso-us-west-auth-token')
25+
TURSO_US_EAST_AUTH_TOKEN=credentials('turso-us-east-auth-token')
26+
WP_REST_API_BASE_URL="https://wp.angular.love"
27+
WP_REST_API_TOKEN=credentials('al-wp-token')
28+
}
29+
30+
stages {
31+
stage("Install dependencies") {
32+
steps {
33+
script {
34+
sh """
35+
corepack enable && corepack prepare [email protected] --activate
36+
pnpm install
37+
"""
38+
}
39+
}
40+
}
41+
stage("Decide environment") {
42+
steps {
43+
script {
44+
env.USE_BRANCH_NAME = env.BRANCH_NAME
45+
env.IS_PR = "FALSE"
46+
env.ENVIRONMENT = 'dev'
47+
env.WORKER_DOMAIN_END = '-blog-bff-dev.contact-ef8.workers.dev'
48+
if (env.BRANCH_NAME == 'main') {
49+
env.ENVIRONMENT = 'prod'
50+
env.WORKER_DOMAIN_END = '-blog-bff.contact-ef8.workers.dev'
51+
}
52+
53+
if (env.CHANGE_ID) {
54+
echo "CHANGE_ID: $CHANGE_ID"
55+
env.IS_PR = "TRUE"
56+
}
57+
58+
// DOn't rember how it worked so for safety for now , todo remove later
59+
if (env.IS_PR == "TRUE" && env.CHANGE_BRANCH != env.BRANCH_NAME) {
60+
echo "Banch missmatch in pr"
61+
echo "CHANGE_BRANCH: $CHANGE_BRANCH"
62+
echo "BRANCH_NAME: $BRANCH_NAME"
63+
env.ENVIRONMENT = 'dev'
64+
env.WORKER_DOMAIN_END = '-blog-bff-dev.contact-ef8.workers.dev'
65+
env.USE_BRANCH_NAME = env.CHANGE_BRANCH
66+
}
67+
68+
if (env.IS_PR == "TRUE") {
69+
pullRequest.comment("PR is detected, will deploy to dev environment")
70+
}
71+
}
72+
}
73+
}
74+
stage("Branch db") {
75+
steps {
76+
script {
77+
def timestamp = new Date().getTime()
78+
def random = Math.abs(new Random().nextInt())
79+
env.BRANCH_HASH = "${random}"
80+
81+
if (env.BRANCH_HASH.length() > 10) {
82+
env.BRANCH_HASH = env.BRANCH_HASH.substring(0, 10)
83+
}
84+
85+
def branchNameForDB = env.USE_BRANCH_NAME
86+
if (env.USE_BRANCH_NAME.length() > 30) {
87+
echo "Branch name is too long, truncating to 30 characters"
88+
branchNameForDB = env.USE_BRANCH_NAME.substring(0, 30)
89+
}
90+
branchNameForDB = branchNameForDB.replace("_", "-")
91+
branchNameForDB = branchNameForDB.replace("/", "-")
92+
branchNameForDB = branchNameForDB.toLowerCase()
93+
94+
env.DB_BRANCH_NAME = "${ENVIRONMENT}-${branchNameForDB}-${BRANCH_HASH}"
95+
if (env.DB_BRANCH_NAME.length() > 50) {
96+
error("DB branch name is too long, truncating to 50 characters")
97+
}
98+
withCredentials([string(credentialsId: 'tursor_api_token', variable: 'TURSO_API_TOKEN')]) {
99+
sh """
100+
turso org switch angular-love
101+
turso db create eu-${DB_BRANCH_NAME} --from-db $TURSO_EU_DB --group blog-eu
102+
turso db create usw-${DB_BRANCH_NAME} --from-db $TURSO_US_WEST_DB --group blog-us-west
103+
turso db create use-${DB_BRANCH_NAME} --from-db $TURSO_US_EAST_DB --group blog-us-east
104+
105+
turso db list | grep -q "eu-${DB_BRANCH_NAME}" || { echo "EU database not found after creation"; exit 1; }
106+
turso db list | grep -q "usw-${DB_BRANCH_NAME}" || { echo "US West database not found after creation"; exit 1; }
107+
turso db list | grep -q "use-${DB_BRANCH_NAME}" || { echo "US East database not found after creation"; exit 1; }
108+
"""
109+
env.TURSO_EU_CONNECTION_URL = "libsql://eu-${DB_BRANCH_NAME}-angular-love.turso.io"
110+
env.TURSO_US_WEST_CONNECTION_URL = "libsql://usw-${DB_BRANCH_NAME}-angular-love.turso.io"
111+
env.TURSO_US_EAST_CONNECTION_URL = "libsql://use-${DB_BRANCH_NAME}-angular-love.turso.io"
112+
}
113+
114+
// clean old branches
115+
build(job: 'angular.love/clean_db_branches', parameters: [
116+
[$class: 'StringParameterValue', name: 'env', value: "${ENVIRONMENT}"],
117+
[$class: 'StringParameterValue', name: 'branchName', value: "${branchNameForDB}"],
118+
[$class: 'StringParameterValue', name: 'branchHash', value: "${BRANCH_HASH}"],
119+
[$class: 'BooleanParameterValue', name: 'dryRun', value: false]])
120+
}
121+
122+
}
123+
}
124+
stage("Deploy bff prod") {
125+
stages {
126+
stage("Prepare secrets") {
127+
steps {
128+
sh """
129+
sed -i "s/<kv_dev_namespace_id>/$KV_DEV/g" apps/blog-bff/wrangler.toml
130+
sed -i "s/<kv_prod_namespace_id>/$KV_PROD/g" apps/blog-bff/wrangler.toml
131+
echo "{
132+
\\"WP_REST_API_BASE_URL\\":\\"$WP_REST_API_BASE_URL\\",
133+
\\"WP_REST_API_TOKEN\\":\\"$WP_REST_API_TOKEN\\",
134+
\\"TURSO_EU_CONNECTION_URL\\":\\"$TURSO_EU_CONNECTION_URL\\",
135+
\\"TURSO_EU_AUTH_TOKEN\\":\\"$TURSO_EU_AUTH_TOKEN\\",
136+
\\"TURSO_US_EAST_CONNECTION_URL\\":\\"$TURSO_US_EAST_CONNECTION_URL\\",
137+
\\"TURSO_US_EAST_AUTH_TOKEN\\":\\"$TURSO_US_EAST_AUTH_TOKEN\\",
138+
\\"TURSO_US_WEST_CONNECTION_URL\\":\\"$TURSO_US_WEST_CONNECTION_URL\\",
139+
\\"TURSO_US_WEST_AUTH_TOKEN\\":\\"$TURSO_US_WEST_AUTH_TOKEN\\"}" > new-secrets-bff
140+
"""
141+
}
142+
}
143+
stage ("Wrangler upload new version") {
144+
steps {
145+
withCredentials([
146+
usernamePassword(credentialsId: 'cf-workers-creds', usernameVariable: 'CLOUDFLARE_ACCOUNT_ID', passwordVariable: 'CLOUDFLARE_API_TOKEN'),
147+
]) {
148+
script {
149+
output = sh(returnStdout: true, script: """
150+
npx wrangler versions upload --config apps/blog-bff/wrangler.toml --env $ENVIRONMENT
151+
""")
152+
echo "Output: $output"
153+
}
154+
}
155+
}
156+
}
157+
stage ("Wrangler upload new secrets") {
158+
steps {
159+
withCredentials([
160+
usernamePassword(credentialsId: 'cf-workers-creds', usernameVariable: 'CLOUDFLARE_ACCOUNT_ID', passwordVariable: 'CLOUDFLARE_API_TOKEN'),
161+
]) {
162+
script {
163+
output = sh(returnStdout: true, script: """
164+
npx wrangler versions secret bulk new-secrets-bff --config apps/blog-bff/wrangler.toml --env $ENVIRONMENT
165+
""")
166+
echo "Output: $output"
167+
def versionId = (output =~ /Created version ([^\s]+)/)[0][1]
168+
env.VERSION_ID = versionId
169+
echo "Version ID: $versionId"
170+
171+
def previewUrl = versionId.substring(0, 8) + env.WORKER_DOMAIN_END
172+
env.PREVIEW_URL = "https://" + previewUrl
173+
env.AL_API_URL = "https://" + previewUrl
174+
echo "Preview URL: $PREVIEW_URL"
175+
}
176+
}
177+
}
178+
}
179+
stage ("Wrangler deploy bff") {
180+
steps {
181+
withCredentials([
182+
usernamePassword(credentialsId: 'cf-workers-creds', usernameVariable: 'CLOUDFLARE_ACCOUNT_ID', passwordVariable: 'CLOUDFLARE_API_TOKEN'),
183+
]) {
184+
sh """
185+
npx wrangler versions deploy --config apps/blog-bff/wrangler.toml --env $ENVIRONMENT $VERSION_ID@100 -y
186+
"""
187+
}
188+
}
189+
}
190+
}
191+
}
192+
stage("sleep") {
193+
steps {
194+
sleep 10
195+
}
196+
}
197+
stage("Build blog") {
198+
steps {
199+
sh """
200+
pnpm run prerender
201+
"""
202+
}
203+
}
204+
stage("Deploy blog prod") {
205+
steps {
206+
script {
207+
withCredentials([
208+
usernamePassword(credentialsId: 'cf-workers-creds', usernameVariable: 'CLOUDFLARE_ACCOUNT_ID', passwordVariable: 'CLOUDFLARE_API_TOKEN'),
209+
]) {
210+
output = sh(returnStdout: true, script: """
211+
npx wrangler pages deploy dist/apps/blog/browser --project-name angular-love-client --branch ${USE_BRANCH_NAME}
212+
""")
213+
echo "Output: $output"
214+
def deploy_url = (output =~ /Take a peek over at ([^\s]+)/)[0][1]
215+
def alias_url = (output =~ /Deployment alias URL: ([^\s]+)/)[0][1]
216+
echo "Deploy URL: $deploy_url"
217+
echo "Alias URL: $alias_url"
218+
env.DEPLOY_URL = deploy_url
219+
env.ALIAS_URL = alias_url
220+
221+
}
222+
}
223+
}
224+
}
225+
stage("Comment on PR") {
226+
when {
227+
expression {
228+
return env.IS_PR == "TRUE"
229+
}
230+
}
231+
steps {
232+
script {
233+
pullRequest.comment("""
234+
Deployed to $ENVIRONMENT environment
235+
Branch: $USE_BRANCH_NAME
236+
BFF URL: $AL_API_URL
237+
Deploy URL: $DEPLOY_URL
238+
Alias URL: $ALIAS_URL
239+
""")
240+
}
241+
}
242+
}
243+
}
244+
post {
245+
always {
246+
cleanWs()
247+
}
248+
failure {
249+
script {
250+
slackSend(channel: '#blog-deployments', message: "Deploy failed, please check the logs in jenkins for more details.")
251+
if (env.IS_PR == "TRUE") {
252+
pullRequest.comment("""
253+
Deploy failed, please check the logs in jenkins for more details.
254+
""")
255+
}
256+
}
257+
}
258+
}
259+
}

apps/blog-bff/wrangler.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ vars = { IS_PROD = "false" }
2121
binding = "CACHE_KV"
2222
id = "<kv_dev_namespace_id>"
2323

24-
[env.prod.observability]
24+
[observability]
2525
enabled = true
26-
head_sampling_rate = 1 # 100% default
26+
head_sampling_rate = 1
27+
28+
[observability.logs]
29+
invocation_logs = true

0 commit comments

Comments
 (0)