Skip to content

Commit 2c63466

Browse files
committed
chore: initial commit
0 parents  commit 2c63466

5 files changed

Lines changed: 285 additions & 0 deletions

File tree

.github/workflows/release.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
paths: [CHANGELOG.md]
6+
branches: [main]
7+
pull_request:
8+
paths: [CHANGELOG.md]
9+
branches: [main]
10+
11+
permissions:
12+
contents: write
13+
pull-requests: write
14+
15+
jobs:
16+
release:
17+
uses: ipdxco/changelog-driven-release/.github/workflows/pr.yml@v1

.github/workflows/stale.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
name: Close and mark stale issue
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
7+
permissions:
8+
issues: write
9+
pull-requests: write
10+
11+
jobs:
12+
stale:
13+
uses: pl-strflt/.github/.github/workflows/reusable-stale-issue.yml@v0.3

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## Unreleased
9+
10+
## [0.1.0] - 2025-02-20
11+
12+
- Initial release of of the dnslink-action

README.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# DNSLink Action
2+
3+
This GitHub Action sets the [DNSLink](https://www.dnslink.dev/) TXT record for a given domain.
4+
5+
Supports the following DNS providers:
6+
7+
- Cloudflare
8+
- DNSimple
9+
10+
This action is built and maintained by [Interplanetary Shipyard](http://ipshipyard.com/).
11+
<a href="http://ipshipyard.com/"><img align="right" src="https://github.com/user-attachments/assets/39ed3504-bb71-47f6-9bf8-cb9a1698f272" /></a>
12+
13+
It's a [composite action](https://docs.github.com/en/actions/sharing-automations/creating-actions/about-custom-actions#composite-actions) that can be called as a step in your workflow to set the DNSLink TXT record for a given domain.
14+
15+
## Inputs
16+
17+
### Required Inputs
18+
19+
| Input | Description |
20+
| --------------------- | ------------------------------------------------------------------------------------------------------------------------ |
21+
| `cid` | CID of the build to update the DNSLink for |
22+
| `dnslink_domain` | Domain to update the DNSLink for e.g. if you set docs.ipfs.tech, the \_dnslink.docs.ipfs.tech TXT record will be updated |
23+
| `cf_record_id` | Cloudflare Record ID |
24+
| `cf_zone_id` | Cloudflare Zone ID |
25+
| `cf_auth_token` | Cloudflare API token |
26+
| `dnsimple_token` | DNSimple API token |
27+
| `dnsimple_account_id` | DNSimple account ID |
28+
29+
### Optional Inputs
30+
31+
| Input | Description |
32+
| ------------------- | ------------------------------------------------------------ |
33+
| `set_github_status` | Set the GitHub commit status with the DNSLink domain and CID |
34+
| `github_token` | GitHub token |
35+
36+
## Usage
37+
38+
Here's a basic example of how to use this action in your workflow:
39+
40+
```yaml
41+
name: Build and Deploy to IPFS
42+
43+
permissions:
44+
contents: read
45+
pull-requests: write
46+
statuses: write
47+
48+
on:
49+
push:
50+
branches:
51+
- main
52+
pull_request:
53+
54+
jobs:
55+
build-and-deploy:
56+
runs-on: ubuntu-latest
57+
outputs: # This exposes the CID output of the action to the rest of the workflow
58+
cid: ${{ steps.deploy.outputs.cid }}
59+
steps:
60+
- name: Checkout code
61+
uses: actions/checkout@v4
62+
63+
- name: Setup Node.js
64+
uses: actions/setup-node@v4
65+
with:
66+
node-version: '20'
67+
cache: 'npm'
68+
69+
- name: Install dependencies
70+
run: npm ci
71+
72+
- name: Build project
73+
run: npm run build
74+
75+
- uses: ipfs/ipfs-deploy-action@v0.3
76+
name: Deploy to IPFS
77+
id: deploy
78+
with:
79+
path-to-deploy: out
80+
storacha-key: ${{ secrets.STORACHA_KEY }}
81+
storacha-proof: ${{ secrets.STORACHA_PROOF }}
82+
github-token: ${{ github.token }}
83+
84+
- uses: ipfs/dnslink-action@v0.1
85+
if: github.ref == 'refs/heads/main' # only update the DNSLink on the main branch
86+
name: Update DNSLink
87+
with:
88+
cid: ${{ steps.deploy.outputs.cid }} # The CID of the build to update the DNSLink for
89+
dnslink_domain: mydomain.com
90+
cf_record_id: ${{ secrets.CF_RECORD_ID }}
91+
cf_zone_id: ${{ secrets.CF_ZONE_ID }}
92+
cf_auth_token: ${{ secrets.CF_AUTH_TOKEN }}
93+
```
94+
95+
## FAQ
96+
97+
- Why not use an infrastructure-as-code tool like [OctoDNS](https://github.com/octodns/octodns) or [DNSControl](https://github.com/StackExchange/dnscontrol)?
98+
- You can! Those are great tools.

action.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: 'DNSLink Action'
2+
description: 'Updates the DNSLink DNS record for a given domain'
3+
branding:
4+
icon: 'box'
5+
color: 'blue'
6+
7+
inputs:
8+
cid:
9+
description: 'CID to update the DNSLink value to'
10+
required: true
11+
dnslink_domain:
12+
description: 'Domain to update the DNSLink for e.g. if you set docs.ipfs.tech, the _dnslink.docs.ipfs.tech TXT record will be updated'
13+
required: true
14+
cf_record_id:
15+
description: 'Cloudflare Record ID'
16+
required: false
17+
cf_zone_id:
18+
description: 'Cloudflare Zone ID'
19+
required: false
20+
cf_auth_token:
21+
description: 'Cloudflare API token'
22+
required: false
23+
dnsimple_token:
24+
description: 'DNSimple API token'
25+
required: false
26+
dnsimple_account_id:
27+
description: 'DNSimple account ID'
28+
required: false
29+
set_github_status:
30+
description: 'Set the GitHub commit status with the DNSLink domain and CID'
31+
default: 'false'
32+
required: false
33+
github_token:
34+
description: 'GitHub token'
35+
required: false
36+
37+
outputs:
38+
dnslink_domain:
39+
description: 'The domain that was updated'
40+
value: ${{ inputs.dnslink_domain }}
41+
dnslink_cid:
42+
description: 'The CID that was set'
43+
value: ${{ inputs.cid }}
44+
45+
runs:
46+
using: 'composite'
47+
steps:
48+
- name: Validate action inputs
49+
shell: bash
50+
run: |
51+
if [[ -z "${{ inputs.dnsimple_token }}" || -z "${{ inputs.dnsimple_account_id }}" ]] && [[ -z "${{ inputs.cf_auth_token }}" || -z "${{ inputs.cf_zone_id }}" || -z "${{ inputs.cf_record_id }}" ]]; then
52+
echo "::error::DNSimple credentials (`dnsimple_token` and `dnsimple_account_id`) or Cloudflare credentials (`cf_auth_token`, `cf_zone_id`, and `cf_record_id`) must be configured"
53+
exit 1
54+
fi
55+
56+
- name: Set up Go
57+
if: inputs.dnsimple_token != ''
58+
uses: actions/setup-go@v4
59+
with:
60+
go-version: '1.23'
61+
62+
- name: Install dnslink-dnsimple
63+
if: inputs.dnsimple_token != ''
64+
shell: bash
65+
run: |
66+
go install github.com/ipfs/dnslink-dnsimple@latest
67+
68+
- name: Update DNSLink in DNSimple
69+
if: inputs.dnsimple_token != ''
70+
shell: bash
71+
env:
72+
DNSIMPLE_TOKEN: ${{ inputs.dnsimple_token }}
73+
DNSIMPLE_ACCOUNT_ID: ${{ inputs.dnsimple_account_id }}
74+
DNSLINK_DOMAIN: ${{ inputs.dnslink_domain }}
75+
DNSLINK_CID: ${{ inputs.cid }}
76+
run: |
77+
if [ -z "${DNSLINK_DOMAIN}" ]; then
78+
echo "Error: dnslink_domain is empty. Skipping DNSLink update."
79+
exit 1
80+
fi
81+
if [ -z "${DNSLINK_CID}" ]; then
82+
echo "Error: CID is empty. Skipping DNSLink update."
83+
exit 1
84+
fi
85+
86+
echo "Updating DNSLink in DNSimple for: ${DNSLINK_DOMAIN}"
87+
dnslink-dnsimple \
88+
-domain "${DNSLINK_DOMAIN}" \
89+
-record "_dnslink" \
90+
-link "/ipfs/${DNSLINK_CID}" \
91+
-token "${DNSIMPLE_TOKEN}" \
92+
-account "${DNSIMPLE_ACCOUNT_ID}"
93+
94+
- name: Update DNSLink in Cloudflare
95+
if: inputs.cf_auth_token != ''
96+
shell: bash
97+
env:
98+
DNSLINK_DOMAIN: ${{ inputs.dnslink_domain }}
99+
DNSLINK_CID: ${{ inputs.cid }}
100+
CF_ZONE_ID: ${{ inputs.cf_zone_id }}
101+
CF_RECORD_ID: ${{ inputs.cf_record_id }}
102+
CF_AUTH_TOKEN: ${{ inputs.cf_auth_token }}
103+
run: |
104+
if [ -z "${DNSLINK_DOMAIN}" ]; then
105+
echo "Error: dnslink_domain is empty. Skipping DNSLink update."
106+
exit 1
107+
fi
108+
if [ -z "${DNSLINK_CID}" ]; then
109+
echo "Error: CID is empty. Skipping DNSLink update."
110+
exit 1
111+
fi
112+
113+
echo "Updating DNSLink for: ${DNSLINK_DOMAIN}"
114+
curl --request PUT \
115+
--header "Authorization: Bearer ${CF_AUTH_TOKEN}" \
116+
--header 'Content-Type: application/json' \
117+
--url "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records/${CF_RECORD_ID}" \
118+
--data "{
119+
\"type\": \"TXT\",
120+
\"name\": \"_dnslink.${DNSLINK_DOMAIN}\",
121+
\"content\": \"dnslink=/ipfs/${DNSLINK_CID}\",
122+
\"comment\": \"${{ github.repository }}/${{ github.sha }}\"
123+
}"
124+
125+
- name: Set GitHub commit status
126+
if: ${{ inputs.set_github_status }}
127+
uses: actions/github-script@v7
128+
with:
129+
github-token: ${{ inputs.github_token }}
130+
script: |
131+
const cid = '${{ inputs.cid }}';
132+
133+
// For PR events, we need to use the head SHA
134+
const sha = context.eventName === 'pull_request'
135+
? context.payload.pull_request.head.sha
136+
: context.sha;
137+
138+
await github.rest.repos.createCommitStatus({
139+
owner: context.repo.owner,
140+
repo: context.repo.repo,
141+
sha: sha,
142+
state: 'success',
143+
description: `${{ inputs.dnslink_domain }} -> ${{ inputs.cid }}`,
144+
context: 'DNSLink'
145+
});

0 commit comments

Comments
 (0)