Skip to content

Commit 31a1568

Browse files
update crosspost dev.to article
1 parent 7ecb8a0 commit 31a1568

File tree

5 files changed

+151
-67
lines changed

5 files changed

+151
-67
lines changed

components/ArticleTag.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ a::before {
3838
color: black;
3939
background-color: #fcdc00;
4040
}
41+
.typescript {
42+
color: white;
43+
background-color: #007acc;
44+
}
4145
.redux {
4246
color: white;
4347
background-color: #764abc;

content/articles/using-git-to-publish-to-dev-to.md renamed to content/articles/using-github-to-crosspost-to-dev-to.md

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
---
2-
title: How you can use github actions to publish to dev.to?
2+
title: Want to crosspost to dev.to? There's a GitHub action for that.
33
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
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: typescript, github, opensource, actions
66
cover_image: https://cdn.nanalyze.com/uploads/2018/07/automation-rpa-teaser.jpg
77
---
88

@@ -17,37 +17,33 @@ Over the last 6 years of Software Development, I've learned a lot, but I've neve
1717
<br>
1818

1919
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).
20+
2. Let's take a look at how to use the [GitHub Action](https://github.com/basicbrogrammer/crosspost-markdown).
2121

2222
# DaCode
2323

2424
The first order of business is to find out if your last commit contains articles.
2525

2626
<br>
2727

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}`)
28+
In order to do so, we first require 2 inputs from the GitHub workflow: github-token & content-dir. These 2 arguments will be retrieved using the [@actions/core](https://github.com/actions/toolkit/tree/main/packages/core) package. The `github-token` argument will be used to initiate an [Octokit Rest client](https://octokit.github.io/rest.js/v18/) using the [@actions/github](https://github.com/actions/toolkit/tree/main/packages/github) package. We can use this instance to request the commit data. Once we have the response, all we have to do is iterate over the list of files and see if the filename match a given content directory (from the `content-dir` argument).
3129

32-
```
33-
34-
<br>
30+
```typescript
31+
import * as core from '@actions/core';
32+
import * as github from '@actions/github';
3533

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()`
34+
export const getFiles = async (): Promise<string[]> => {
35+
const octokit = github.getOctokit(core.getInput('github-token'));
3736

38-
<br>
37+
const commit = await octokit.repos.getCommit({
38+
...github.context.repo,
39+
ref: github.context.sha,
40+
});
3941

40-
Putting it all together looks something like this:
41-
42-
```javascript
43-
const { execSync } = require('child_process');
42+
return (commit?.data?.files || [])
43+
.map((file: any) => file.filename)
44+
.filter((filename: string) => filename.includes(core.getInput('content-dir')));
45+
};
4446

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());
5147
```
5248

5349
If this code finds markdown files, we will cycle through each file, sending it into a `publish` function.
@@ -58,24 +54,39 @@ We will use node's file system [`readFileSync`](https://nodejs.org/api/fs.html#f
5854
If the frontmatter indicates the post is `published`, we can go ahead and start crossposting.
5955
Let's have a look at the current version of the `publish` function.
6056

61-
```javascript
62-
exports.publish = (path) => {
57+
```typescript
58+
import * as core from '@actions/core';
59+
import * as fs from 'fs';
60+
import devTo from './dev-to';
61+
62+
const frontmatter = require('@github-docs/frontmatter');
63+
64+
const logResponse = async (title: string, destination: string, publishCallback: Promise<any>): Promise<void> => {
65+
const {status} = await publishCallback;
66+
console.table({title, destination, status});
67+
};
68+
69+
const publish = async (path: string): Promise<void> => {
6370
try {
6471
const markdown = fs.readFileSync(`./${path}`, 'utf8');
65-
const { data } = frontmatter(markdown);
72+
const {data} = frontmatter(markdown);
6673

6774
if (data.published) {
68-
logResponse(data.title, 'Dev.to', devTo.publish(markdown));
75+
if (core.getInput('dev-to-token').length > 0) {
76+
logResponse(data.title, 'Dev.to', devTo.publish(markdown));
77+
}
6978
} else {
7079
console.log(`Article ${data.title} NOT published. Skipping.`);
7180
}
7281
} catch (err) {
73-
console.error(err);
82+
core.setFailed(err.message);
7483
}
7584
};
85+
86+
export default publish;
7687
```
7788

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. 🤙
89+
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. 🤙
7990

8091
<br>
8192

@@ -86,13 +97,17 @@ The `devTo.publish` method uses the auth token and [node-fetch](https://www.npmj
8697

8798
And here is the dead simple code for our DevTo class:
8899

89-
```javascript
100+
```typescript
101+
import fetch from 'node-fetch';
102+
import * as core from '@actions/core';
103+
90104
class DevTo {
105+
token: string;
91106
constructor() {
92107
this.token = core.getInput('dev-to-token');
93108
}
94109

95-
publish(body_markdown) {
110+
async publish(body_markdown: string): Promise<any> {
96111
const body = {
97112
article: {
98113
body_markdown,
@@ -106,26 +121,26 @@ class DevTo {
106121
'Content-Type': 'application/json',
107122
'api-key': this.token,
108123
},
109-
}).then((response) => response.json());
124+
}).then((response: any) => response.json());
110125
}
111126
}
112127

113-
module.exports = new DevTo();
128+
export default new DevTo();
114129
```
115130

116131
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!
117132

118133
# DaAction
119134

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 😎.
135+
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 😎.
121136

122137
<br>
123138

124-
Let's take a look at how you can use this action in your Github blog repo.
139+
Let's take a look at how you can use this action in your GitHub blog repo.
125140

126141
<br>
127142

128-
Inside your Github repo, add a workflow file. Mine is `.github/workflows/crosspost.yml`.
143+
Inside your GitHub repo, add a workflow file. Mine is `.github/workflows/crosspost.yml`.
129144

130145
<br>
131146

@@ -141,6 +156,7 @@ on:
141156
```
142157
143158
Next, we need to start writing the yaml for the job itself. First, we will check out the code:
159+
144160
```yaml
145161
jobs:
146162
crosspost:
@@ -154,7 +170,7 @@ Super simple.
154170
155171
<br>
156172
157-
Next step will be to run the crosspost-markdown action and pass in the necessary arguments (content-dir & dev-to-token).
173+
Next step will be to run the crosspost-markdown action and pass in the necessary arguments (content-dir & dev-to-token). These can be set in the [secrets](https://docs.github.com/en/free-pro-team@latest/actions/reference/encrypted-secrets) section of your repo's settings.
158174
159175
```yaml
160176
jobs:
@@ -164,13 +180,14 @@ jobs:
164180
- name: Checkout Code
165181
uses: actions/checkout@v2
166182

167-
- uses: basicBrogrammer/crosspost-markdown@v0.5
183+
- uses: basicBrogrammer/crosspost-markdown@v0.1.0 # remember to see what the latest version is 8)
168184
with:
169185
content-dir: './content/articles/'
170186
dev-to-token: ${{ secrets.DEV_TO }}
187+
github-token: ${{ secrets.GITHUB_TOKEN }}
171188
```
172189
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.
190+
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.
174191
175192
<br>
176193

nuxt.config.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,15 @@ export default {
4848

4949
// Build Configuration (https://go.nuxtjs.dev/config-build)
5050
build: {},
51+
// needed to generate dynamic tags that aren't in links
52+
generate: {
53+
async routes() {
54+
const { $content } = require('@nuxt/content')
55+
const dynamicRoutes = await $content('articles').only(['slug']).fetch()
56+
57+
return dynamicRoutes.map((myroute) =>
58+
myroute.slug === '/index' ? '/' : '/blog/' + myroute.slug
59+
)
60+
},
61+
},
5162
}

0 commit comments

Comments
 (0)