Skip to content

Commit e5f2daa

Browse files
committed
Initial implementation of k61.dev URL shortener
- Project structure with workers, functions, web, and landing directories - Cloudflare Worker for edge redirects (<10ms performance) - Azure Functions API (CRUD, click tracking, user management) - React frontend with dashboard, create URL, and settings pages - Landing page for www.k61.dev - GitHub Actions CI/CD for automated deployments - Comprehensive documentation (PLAN.md, GETTING-STARTED.md)
0 parents  commit e5f2daa

Some content is hidden

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

45 files changed

+2912
-0
lines changed

.eslintrc.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"env": {
3+
"es2021": true,
4+
"node": true
5+
},
6+
"extends": ["eslint:recommended"],
7+
"parserOptions": {
8+
"ecmaVersion": "latest",
9+
"sourceType": "module"
10+
},
11+
"rules": {
12+
"no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
13+
"no-console": "off"
14+
}
15+
}

.github/workflows/README.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# GitHub Actions CI/CD
2+
3+
This directory contains automated deployment workflows.
4+
5+
## Workflows
6+
7+
### deploy-worker.yml
8+
Deploys Cloudflare Worker on changes to `workers/` directory.
9+
10+
**Required Secrets:**
11+
- `CLOUDFLARE_API_TOKEN` - Cloudflare API token with Workers deploy permissions
12+
- `AZURE_STORAGE_ACCOUNT` - Azure storage account name
13+
- `AZURE_STORAGE_KEY` - Azure storage account key
14+
- `INTERNAL_API_KEY` - Secure random key for internal API
15+
16+
### deploy-functions.yml
17+
Deploys Azure Functions on changes to `functions/` directory.
18+
19+
**Required Secrets:**
20+
- `AZURE_FUNCTIONAPP_NAME` - Name of Azure Function App
21+
- `AZURE_FUNCTIONAPP_PUBLISH_PROFILE` - Publish profile from Azure Portal
22+
23+
### deploy-web.yml
24+
Deploys web app (url.k61.dev) on changes to `web/` directory.
25+
26+
**Required Secrets:**
27+
- `AZURE_STATIC_WEB_APPS_API_TOKEN_WEB` - Deployment token from Azure Static Web Apps
28+
29+
### deploy-landing.yml
30+
Deploys landing page (www.k61.dev) on changes to `landing/` directory.
31+
32+
**Required Secrets:**
33+
- `AZURE_STATIC_WEB_APPS_API_TOKEN_LANDING` - Deployment token from Azure Static Web Apps
34+
35+
### test.yml
36+
Runs tests and linting on all pushes and pull requests.
37+
38+
## Setup
39+
40+
1. Create Azure resources (Storage, Functions, Static Web Apps)
41+
2. Get deployment credentials from Azure Portal
42+
3. Add secrets to GitHub repository settings
43+
4. Push to main branch to trigger deployments
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Deploy Azure Functions
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'functions/**'
8+
- '.github/workflows/deploy-functions.yml'
9+
10+
jobs:
11+
build-and-deploy:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Setup Node.js
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: '20'
20+
21+
- name: Install dependencies
22+
working-directory: ./functions
23+
run: npm install
24+
25+
- name: Build TypeScript
26+
working-directory: ./functions
27+
run: npm run build
28+
29+
- name: Deploy to Azure Functions
30+
uses: Azure/functions-action@v1
31+
with:
32+
app-name: ${{ secrets.AZURE_FUNCTIONAPP_NAME }}
33+
package: './functions'
34+
publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Deploy Landing Page (www.k61.dev)
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'landing/**'
8+
- '.github/workflows/deploy-landing.yml'
9+
10+
jobs:
11+
build-and-deploy:
12+
runs-on: ubuntu-latest
13+
name: Build and Deploy
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: '20'
21+
22+
- name: Install dependencies
23+
working-directory: ./landing
24+
run: npm install
25+
26+
- name: Build
27+
working-directory: ./landing
28+
run: npm run build
29+
30+
- name: Deploy to Azure Static Web Apps
31+
uses: Azure/static-web-apps-deploy@v1
32+
with:
33+
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_LANDING }}
34+
repo_token: ${{ secrets.GITHUB_TOKEN }}
35+
action: 'upload'
36+
app_location: '/landing'
37+
output_location: 'dist'

.github/workflows/deploy-web.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Deploy Web App (url.k61.dev)
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'web/**'
8+
- '.github/workflows/deploy-web.yml'
9+
10+
jobs:
11+
build-and-deploy:
12+
runs-on: ubuntu-latest
13+
name: Build and Deploy
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: '20'
21+
22+
- name: Install dependencies
23+
working-directory: ./web
24+
run: npm install
25+
26+
- name: Build
27+
working-directory: ./web
28+
run: npm run build
29+
30+
- name: Deploy to Azure Static Web Apps
31+
uses: Azure/static-web-apps-deploy@v1
32+
with:
33+
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_WEB }}
34+
repo_token: ${{ secrets.GITHUB_TOKEN }}
35+
action: 'upload'
36+
app_location: '/web'
37+
output_location: 'dist'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Deploy Cloudflare Worker
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- 'workers/**'
8+
- '.github/workflows/deploy-worker.yml'
9+
10+
jobs:
11+
deploy:
12+
runs-on: ubuntu-latest
13+
name: Deploy Worker
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: '20'
21+
22+
- name: Install dependencies
23+
working-directory: ./workers
24+
run: npm install
25+
26+
- name: Deploy to Cloudflare Workers
27+
uses: cloudflare/wrangler-action@v3
28+
with:
29+
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
30+
workingDirectory: './workers'
31+
secrets: |
32+
AZURE_STORAGE_ACCOUNT
33+
AZURE_STORAGE_KEY
34+
INTERNAL_API_KEY
35+
env:
36+
AZURE_STORAGE_ACCOUNT: ${{ secrets.AZURE_STORAGE_ACCOUNT }}
37+
AZURE_STORAGE_KEY: ${{ secrets.AZURE_STORAGE_KEY }}
38+
INTERNAL_API_KEY: ${{ secrets.INTERNAL_API_KEY }}

.github/workflows/test.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Run Tests
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Setup Node.js
16+
uses: actions/setup-node@v4
17+
with:
18+
node-version: '20'
19+
20+
- name: Install root dependencies
21+
run: npm install
22+
23+
- name: Run linter
24+
run: npm run lint
25+
26+
- name: Run tests
27+
run: npm test

.gitignore

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Dependencies
2+
node_modules/
3+
package-lock.json
4+
5+
# Environment variables
6+
.env
7+
.env.local
8+
.env.*.local
9+
local.settings.json
10+
11+
# Build outputs
12+
dist/
13+
build/
14+
*.js.map
15+
16+
# Azure Functions
17+
bin/
18+
obj/
19+
.azurefunctions/
20+
21+
# IDE
22+
.vscode/
23+
.idea/
24+
*.swp
25+
*.swo
26+
*~
27+
28+
# OS
29+
.DS_Store
30+
Thumbs.db
31+
32+
# Logs
33+
*.log
34+
npm-debug.log*
35+
yarn-debug.log*
36+
yarn-error.log*
37+
38+
# Testing
39+
coverage/
40+
.nyc_output/
41+
42+
# Cloudflare Workers
43+
.wrangler/
44+
wrangler.toml.backup
45+
46+
# Azure
47+
*.pubxml
48+
*.publishsettings
49+
50+
# Temporary files
51+
*.tmp
52+
.cache/

.prettierrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "es5",
4+
"singleQuote": true,
5+
"printWidth": 100,
6+
"tabWidth": 2,
7+
"useTabs": false
8+
}

0 commit comments

Comments
 (0)