Skip to content

Commit cd8807f

Browse files
committed
add automation for dns sync
1 parent 18dca95 commit cd8807f

File tree

9 files changed

+473
-0
lines changed

9 files changed

+473
-0
lines changed

Diff for: .github/workflows/sync-sub-domains.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Sync Sub-domains
2+
on:
3+
push:
4+
branches:
5+
- master
6+
jobs:
7+
sync:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout
11+
uses: actions/checkout@v2
12+
13+
- name: install dependencies
14+
working-directory: domain
15+
run: npm ci
16+
17+
- name: Sync sub-domains
18+
working-directory: domain
19+
run: node sync.js
20+
env:
21+
API_KEY: ${{ secrets.DNS_API_KEY }}
22+
API_SECRET: ${{ secrets.DNS_API_SECRET }}

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ dist
102102

103103
# TernJS port file
104104
.tern-port
105+
106+
domain/.secrets

Diff for: domain/list/eugene.yml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: eugene
2+
repo: loreanvictor.github.io
3+
contact: https://github.com/loreanvictor

Diff for: domain/list/tysonwilliams.yml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
name: tysonwilliams
2+
repo: tysonmn.github.io
3+
contact: https://github.com/TysonMN

Diff for: domain/live.js

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import fetch from 'node-fetch'
2+
import createHttpError from 'http-errors'
3+
4+
// TODO: extract a separate package from this
5+
6+
const BASE_URL = 'https://porkbun.com/api/json/v3/dns/'
7+
const DOMAIN = 'coding.blog'
8+
9+
const SUBDOMAIN_PATTERN = /^([a-z0-9-]+)\.coding\.blog$/
10+
11+
12+
export async function getLiveBlogs() {
13+
const response = await fetch(`${BASE_URL}retrieve/${DOMAIN}`, {
14+
method: 'POST',
15+
body: JSON.stringify({
16+
apikey: process.env.API_KEY,
17+
secretapikey: process.env.API_SECRET,
18+
})
19+
})
20+
21+
if (response.ok) {
22+
const data = await response.json()
23+
24+
return data.records
25+
.filter(record =>
26+
record.type === 'CNAME' &&
27+
SUBDOMAIN_PATTERN.test(record.name) &&
28+
record.name.substring(0, 4) !== 'www.'
29+
)
30+
.map(record => ({
31+
name: record.name.split('.')[0],
32+
repo: record.content,
33+
}))
34+
} else {
35+
throw createHttpError(response.status, response.statusText)
36+
}
37+
}
38+
39+
40+
export async function addLiveBlog(name, repo) {
41+
const response = await fetch(`${BASE_URL}create/${DOMAIN}`, {
42+
method: 'POST',
43+
body: JSON.stringify({
44+
apikey: process.env.API_KEY,
45+
secretapikey: process.env.API_SECRET,
46+
type: 'CNAME',
47+
name,
48+
content: repo,
49+
})
50+
})
51+
52+
if (!response.ok) {
53+
throw createHttpError(response.status, response.statusText)
54+
}
55+
}
56+
57+
58+
export async function updateLiveBlog(name, repo) {
59+
const response = await fetch(`${BASE_URL}editByNameType/${DOMAIN}/CNAME/${name}`, {
60+
method: 'POST',
61+
body: JSON.stringify({
62+
apikey: process.env.API_KEY,
63+
secretapikey: process.env.API_SECRET,
64+
content: repo,
65+
})
66+
})
67+
68+
if (!response.ok) {
69+
throw createHttpError(response.status, response.statusText)
70+
}
71+
}
72+
73+
74+
export async function deleteLiveBlog(name) {
75+
const response = await fetch(`${BASE_URL}deleteByNameType/${DOMAIN}/CNAME/${name}`, {
76+
method: 'POST',
77+
body: JSON.stringify({
78+
apikey: process.env.API_KEY,
79+
secretapikey: process.env.API_SECRET,
80+
})
81+
})
82+
83+
if (!response.ok) {
84+
throw createHttpError(response.status, response.statusText)
85+
}
86+
}

Diff for: domain/local.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import yaml from 'yaml'
2+
import { fileURLToPath } from 'url'
3+
import { join, dirname, extname } from 'path'
4+
import { readFile, readdir } from 'fs/promises'
5+
6+
7+
export async function getLocalBlogs() {
8+
const files = await readdir(join(dirname(fileURLToPath(import.meta.url)), 'list'))
9+
10+
return await Promise.all(files
11+
.filter(file => extname(file) === '.yml')
12+
.map(async file => {
13+
const content = await readFile(join(dirname(fileURLToPath(import.meta.url)), 'list', file), 'utf8')
14+
15+
return yaml.parse(content)
16+
})
17+
)
18+
}

0 commit comments

Comments
 (0)