Skip to content

Commit db7cc3d

Browse files
committed
feat: merged main and made minor styling fixes
2 parents 87d4b61 + 3be6ade commit db7cc3d

File tree

151 files changed

+7290
-3675
lines changed

Some content is hidden

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

151 files changed

+7290
-3675
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: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
FROM node:22.13-slim AS base
1+
FROM node:22.14.0-slim AS base
22
ENV PNPM_HOME="/pnpm"
33
ENV PATH="$PNPM_HOME:$PATH"
44
RUN corepack enable
55

66
RUN apt-get update && apt-get install -y jq && apt-get install -y curl
77

8+
COPY --from=golang:1.24.1-alpine /usr/local/go/ /usr/local/go/
9+
ENV PATH="/usr/local/go/bin:${PATH}"
10+
RUN mkdir -p /go
11+
ENV GOPATH="/go"
12+
ENV PATH="/go/bin:$PATH"
13+
RUN go install github.com/tursodatabase/turso-cli/cmd/[email protected]
14+
815
COPY . /app
916
WORKDIR /app

Jenkinsfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ pipeline {
2828
steps {
2929
script {
3030
sh """
31-
corepack enable && corepack prepare pnpm@9.15.2 --activate
32-
pnpm install
31+
corepack enable && corepack prepare pnpm@10.6.2 --activate
32+
pnpm install
3333
"""
3434
}
3535
}
@@ -44,7 +44,7 @@ pipeline {
4444
sed -i "s/<kv_prod_namespace_id>/$KV_PROD/g" apps/blog-bff/wrangler.toml
4545
npx wrangler deploy --config apps/blog-bff/wrangler.toml --env dev
4646
npx wrangler deploy --config apps/blog-bff/wrangler.toml --env prod
47-
"""
47+
"""
4848
}
4949
}
5050
}

Jenkinsfile.deploy

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

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

apps/blog/scripts/build-routes.mjs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const BASE_URL = process.env.AL_BASE_URL;
77
const SSG_ROUTES_FILE_PATH = 'apps/blog/routes.txt';
88
const SITEMAP_FILE_PATH = 'apps/blog/src/sitemap.xml';
99
const ROOT_PATHS_FILE_PREFIX = 'apps/blog/src/assets/root-paths';
10+
const BANNERS_FILE_PREFIX = 'apps/blog/src/assets/banners';
1011

1112
const SUPPORTED_LANGUAGES = ['pl', 'en'];
1213
const DEFAULT_LANGUAGE = 'en';
@@ -100,6 +101,37 @@ async function fetchAuthorRoutes(lang, skip = 0, take = 50) {
100101
}
101102
}
102103

104+
/**
105+
* Fetches banners.
106+
* @returns {Promise<void>}
107+
*/
108+
async function fetchBannersAndWriteToFile() {
109+
const url = `${API_BASE_URL}/banners`;
110+
try {
111+
const data = await fetch(url).then((resp) => resp.json());
112+
113+
const stream = createWriteStream(`${BANNERS_FILE_PREFIX}.json`, {
114+
encoding: 'utf-8',
115+
});
116+
117+
stream.on('error', (error) => {
118+
console.error('Error writing paths to file:', error);
119+
});
120+
121+
try {
122+
stream.write(JSON.stringify({ banners: data }));
123+
} catch (error) {
124+
console.error('Error during write operation:', error);
125+
throw error;
126+
} finally {
127+
stream.end();
128+
}
129+
} catch (error) {
130+
console.error('Failed to fetch banners');
131+
throw error;
132+
}
133+
}
134+
103135
/**
104136
* Appends static paths to the routes array for a given language.
105137
* @param {"pl" | "en"} lang
@@ -182,6 +214,7 @@ async function main() {
182214
await Promise.all([
183215
...SUPPORTED_LANGUAGES.map((lang) => fetchArticleRoutes(lang)),
184216
...SUPPORTED_LANGUAGES.map((lang) => fetchAuthorRoutes(lang)),
217+
fetchBannersAndWriteToFile(),
185218
]);
186219

187220
SUPPORTED_LANGUAGES.forEach((lang) => {

0 commit comments

Comments
 (0)