Skip to content

Commit 7ecb8a0

Browse files
update crosspost.yml
1 parent 28bb4fa commit 7ecb8a0

File tree

9 files changed

+260
-70
lines changed

9 files changed

+260
-70
lines changed

.github/workflows/crosspost.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: CrossPost
2+
3+
on:
4+
push:
5+
paths:
6+
- 'content/articles/*.md'
7+
8+
jobs:
9+
crosspost:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout Code
13+
uses: actions/checkout@v2
14+
15+
- uses: basicBrogrammer/crosspost-markdown@v0.1.0
16+
with:
17+
content-dir: 'content/articles/'
18+
dev-to-token: ${{ secrets.DEV_TO }}
19+
github-token: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/publish-to-dev-to.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

assets/global.css

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,51 @@
1+
html {
2+
font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
3+
Roboto, 'Helvetica Neue', Arial, sans-serif;
4+
font-size: 16px;
5+
word-spacing: 1px;
6+
-ms-text-size-adjust: 100%;
7+
-webkit-text-size-adjust: 100%;
8+
-moz-osx-font-smoothing: grayscale;
9+
-webkit-font-smoothing: antialiased;
10+
box-sizing: border-box;
11+
background-color: #f4f0ec;
12+
}
13+
14+
*,
15+
*::before,
16+
*::after {
17+
box-sizing: border-box;
18+
margin: 0;
19+
}
20+
21+
.color-primary {
22+
color: #ff124f;
23+
}
24+
.color-secondary {
25+
color: #7a04eb;
26+
}
27+
.border-primary {
28+
border-color: #ff124f;
29+
}
30+
.border-secondary {
31+
border-color: #7a04eb;
32+
}
33+
34+
.button--primary {
35+
display: inline-block;
36+
border-radius: 4px;
37+
border: 1px solid #ff124f;
38+
color: #ff124f;
39+
text-decoration: none;
40+
padding: 10px 30px;
41+
}
42+
43+
.button--primary:hover {
44+
color: #fff;
45+
background-color: #ff124f;
46+
}
47+
48+
149
.nuxt-content h1 {
250
color: #ff124f;
351
@apply font-bold text-2xl;
@@ -21,6 +69,11 @@
2169
.nuxt-content .nuxt-content-highlight {
2270
@apply border-2 rounded-lg my-1;
2371
}
72+
73+
.nuxt-content p > code {
74+
@apply border-2 rounded-lg;
75+
}
76+
2477
.nuxt-content img {
2578
margin: 0 auto;
2679
}

components/ArticleTag.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,8 @@ a::before {
4343
background-color: #764abc;
4444
border-color: black;
4545
}
46+
.opensource {
47+
color: white;
48+
background-color: green;
49+
}
4650
</style>
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: How you can use github actions to publish to dev.to?
3+
published: false
4+
description: When I create a new markdown article, I don't want to have copy and paste that markdown to multiple other blog sites. So, why not let an octocat handle this work for me with a github action?
5+
tags: javascript, github, opensource, actions
6+
cover_image: https://cdn.nanalyze.com/uploads/2018/07/automation-rpa-teaser.jpg
7+
---
8+
9+
# If a tree falls in the woods, does it make a sound?
10+
11+
The internet is much like a forest with content and sites being like trees. There are thousands of trees growing in the forest off the beaten path that no one knows about. If you want your site or content to be discovered, the easiest way is to plant your tree close to the main trail.
12+
13+
<br>
14+
15+
Over the last 6 years of Software Development, I've learned a lot, but I've never shared it outside of my full-time job. If there's not an easy way for people to find the blogs I put out, then I'm still not sharing my thoughts with others. This is where sites like [dev.to](https://dev.to/basicbrogrammer) and [hashnode](https://hashnode.com/@basicbrogrammer) come into play. I can write the markdown for my blog posts in vim then crosspost to other blog distribution platforms. I definitely didn't want to copypasta all my content every time, so I've decided to automate this process and open-source it.
16+
17+
<br>
18+
19+
1. Let's go over the code.
20+
2. Let's take a look at how to use the [github action](https://github.com/basicbrogrammer/crosspost-markdown).
21+
22+
# DaCode
23+
24+
The first order of business is to find out if your last commit contains articles.
25+
26+
<br>
27+
28+
In order to do so, we will use node's [execSync](https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options) function to run a git command which will give us the names of files changed in the given path argument.
29+
```javascript
30+
execSync(`git diff-tree --no-commit-id --name-only -r ${process.env.GITHUB_SHA} -- ${path}`)
31+
32+
```
33+
34+
<br>
35+
36+
Let's take the return value turn it into a string, split the string up by line breaks, filter off any empty strings, and finally remove any leading and trailing whitespace with `trim()`
37+
38+
<br>
39+
40+
Putting it all together looks something like this:
41+
42+
```javascript
43+
const { execSync } = require('child_process');
44+
45+
exports.findFiles = (path) =>
46+
execSync(`git diff-tree --no-commit-id --name-only -r ${process.env.GITHUB_SHA} -- ${path}`)
47+
.toString()
48+
.split('\n')
49+
.filter((f) => f.length > 0)
50+
.map((f) => f.trim());
51+
```
52+
53+
If this code finds markdown files, we will cycle through each file, sending it into a `publish` function.
54+
We will use node's file system [`readFileSync`](https://nodejs.org/api/fs.html#fs_fs_readfilesync_path_options) function to read the file into memory. Then, using the [`@github-docs/frontmatter`](https://github.com/docs/frontmatter) package to parse the markdown so we can checkout the [frontmatter](https://jekyllrb.com/docs/front-matter/) which is just the "data" at the top of markdown files.
55+
56+
<br>
57+
58+
If the frontmatter indicates the post is `published`, we can go ahead and start crossposting.
59+
Let's have a look at the current version of the `publish` function.
60+
61+
```javascript
62+
exports.publish = (path) => {
63+
try {
64+
const markdown = fs.readFileSync(`./${path}`, 'utf8');
65+
const { data } = frontmatter(markdown);
66+
67+
if (data.published) {
68+
logResponse(data.title, 'Dev.to', devTo.publish(markdown));
69+
} else {
70+
console.log(`Article ${data.title} NOT published. Skipping.`);
71+
}
72+
} catch (err) {
73+
console.error(err);
74+
}
75+
};
76+
```
77+
78+
Currently, I am only crossposting to [dev.to](https://dev.to/basicbrogrammer), but soon I want to update the Github action to crosspost to [hashnode.com](https://hashnode.com/@basicBrogrammer) as well. 🤙
79+
80+
<br>
81+
82+
To crosspost to dev.to, the publish function passes the markdown into the `publish` method on an authenticated instance of DevTo.
83+
The `devTo.publish` method uses the auth token and [node-fetch](https://www.npmjs.com/package/node-fetch) to POST your markdown to dev.to's api and boom it's done.
84+
85+
<br>
86+
87+
And here is the dead simple code for our DevTo class:
88+
89+
```javascript
90+
class DevTo {
91+
constructor() {
92+
this.token = core.getInput('dev-to-token');
93+
}
94+
95+
publish(body_markdown) {
96+
const body = {
97+
article: {
98+
body_markdown,
99+
},
100+
};
101+
102+
return fetch('https://dev.to/api/articles', {
103+
method: 'post',
104+
body: JSON.stringify(body),
105+
headers: {
106+
'Content-Type': 'application/json',
107+
'api-key': this.token,
108+
},
109+
}).then((response) => response.json());
110+
}
111+
}
112+
113+
module.exports = new DevTo();
114+
```
115+
116+
That's really it. That's all the code needed to keep you from having to copy and paste your blog markdown to multiple distributors!
117+
118+
# DaAction
119+
120+
As I was writing this code, I was like why don't I make it a Github action and share it with anyone that would like to use it. So I did 😎.
121+
122+
<br>
123+
124+
Let's take a look at how you can use this action in your Github blog repo.
125+
126+
<br>
127+
128+
Inside your Github repo, add a workflow file. Mine is `.github/workflows/crosspost.yml`.
129+
130+
<br>
131+
132+
I'm using [nuxt's content module](https://content.nuxtjs.org/) to build my blog, and have it configured to look for blog posts in the `./content/articles/` directory. So, let's tell our action to only run when a file is changed in that directory:
133+
134+
```yaml
135+
name: CrossPost
136+
137+
on:
138+
push:
139+
paths:
140+
- './content/articles/*'
141+
```
142+
143+
Next, we need to start writing the yaml for the job itself. First, we will check out the code:
144+
```yaml
145+
jobs:
146+
crosspost:
147+
runs-on: ubuntu-latest
148+
steps:
149+
- name: Checkout Code
150+
uses: actions/checkout@v2
151+
```
152+
153+
Super simple.
154+
155+
<br>
156+
157+
Next step will be to run the crosspost-markdown action and pass in the necessary arguments (content-dir & dev-to-token).
158+
159+
```yaml
160+
jobs:
161+
crosspost:
162+
runs-on: ubuntu-latest
163+
steps:
164+
- name: Checkout Code
165+
uses: actions/checkout@v2
166+
167+
- uses: basicBrogrammer/crosspost-markdown@v0.5
168+
with:
169+
content-dir: './content/articles/'
170+
dev-to-token: ${{ secrets.DEV_TO }}
171+
```
172+
173+
All done. Now when you push to your repo the Github action will run and if you have any new blog posts it will publish them to dev.to.
174+
175+
<br>
176+
177+
## [Cache me on Tweeter, HowBowDat? Click Me. I dare you.](https://twitter.com/basicbrogrammer)

layouts/default.vue

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@
2828
</transition>
2929
<article class="w-screen p-4 md:w-3/4">
3030
<div class="mx-auto w-full md:w-3/4">
31-
<Banner>
32-
<h2><b>WARNING:</b> Work in Progress.</h2>
33-
<p>Some Pages may be unfinished or broken. Enjoy.</p>
34-
</Banner>
3531
<Nuxt />
3632
</div>
3733
</article>
@@ -40,10 +36,9 @@
4036
</template>
4137
<script>
4238
import SideBar from '@/components/SideBar'
43-
import Banner from '@/components/Banner'
4439
4540
export default {
46-
components: { SideBar, Banner },
41+
components: { SideBar },
4742
data() {
4843
return {
4944
sideNavOpen: false,
@@ -74,60 +69,14 @@ export default {
7469
</script>
7570

7671
<style>
77-
html {
78-
font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
79-
Roboto, 'Helvetica Neue', Arial, sans-serif;
80-
font-size: 16px;
81-
word-spacing: 1px;
82-
-ms-text-size-adjust: 100%;
83-
-webkit-text-size-adjust: 100%;
84-
-moz-osx-font-smoothing: grayscale;
85-
-webkit-font-smoothing: antialiased;
86-
box-sizing: border-box;
87-
background-color: #f4f0ec;
88-
}
8972
.navbar {
9073
background-color: #f4f0ec;
9174
}
9275
93-
*,
94-
*::before,
95-
*::after {
96-
box-sizing: border-box;
97-
margin: 0;
98-
}
99-
10076
.btn-sidebar {
10177
@apply px-3 rounded-lg;
10278
}
10379
104-
.color-primary {
105-
color: #ff124f;
106-
}
107-
.color-secondary {
108-
color: #7a04eb;
109-
}
110-
.border-primary {
111-
border-color: #ff124f;
112-
}
113-
.border-secondary {
114-
border-color: #7a04eb;
115-
}
116-
117-
.button--primary {
118-
display: inline-block;
119-
border-radius: 4px;
120-
border: 1px solid #ff124f;
121-
color: #ff124f;
122-
text-decoration: none;
123-
padding: 10px 30px;
124-
}
125-
126-
.button--primary:hover {
127-
color: #fff;
128-
background-color: #ff124f;
129-
}
130-
13180
/* Enter and leave animations can use different
13281
durations and timing functions. */
13382
.sidebar-slide-enter-active {
@@ -153,6 +102,7 @@ html {
153102
@media only screen and (max-width: 767px) {
154103
.main-body {
155104
height: 95vh;
105+
overflow-y: auto;
156106
}
157107
}
158108
</style>

nuxt.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77

88
// Global page headers (https://go.nuxtjs.dev/config-head)
99
head: {
10-
title: 'blog',
10+
title: 'Basically Brogramming',
1111
meta: [
1212
{ charset: 'utf-8' },
1313
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },

pages/blog/_slug.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
<h1 class="color-primary text-3xl font-extrabold my-1">
55
{{ article.title }}
66
</h1>
7-
<ArticleTag v-for="tag in tags" :key="tag" :tag="tag" />
7+
<div class="m-2 flex flex-wrap">
8+
<ArticleTag v-for="tag in tags" :key="tag" :tag="tag" />
9+
</div>
810
<nuxt-content :document="article" class="my-2" />
911
</div>
1012
</template>

0 commit comments

Comments
 (0)