Skip to content

Commit

Permalink
hashnode uploads
Browse files Browse the repository at this point in the history
  • Loading branch information
codercatdev committed Dec 18, 2023
1 parent 1d6c789 commit 8cbe7c1
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 0 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/syndicate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,53 @@ jobs:
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: main-devto updates
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: dev-devto updates
branch: dev
hashnode:
environment: main
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
token: ${{ secrets.PAT }}
- uses: actions/setup-node@v4
name: Install node
with:
node-version: 18
- uses: pnpm/action-setup@v2
name: Install pnpm
with:
version: 8
run_install: false
- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
working-directory: ./apps/codingcatdev
run: pnpm i
- name: syndicate:post-hashnode
working-directory: ./apps/codingcatdev/scripts
run: node post-hashnode.js
env:
PRIVATE_DEVTO: ${{ secrets.PRIVATE_DEVTO }}
- name: syndicate:podcast-hashnode
working-directory: ./apps/codingcatdev/scripts
run: node podcast-hashnode.js
env:
PRIVATE_DEVTO: ${{ secrets.PRIVATE_DEVTO }}
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: main-devto updates
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: dev-devto updates
Expand Down
125 changes: 125 additions & 0 deletions apps/codingcatdev/scripts/post-hashnode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* You can test this using act
* run act -s PRIVATE_DEVTO=yourapikey
*/

import { Glob } from 'glob';
import matter from 'gray-matter';
import fs from 'fs';

const TYPE = 'post';
const BASE = `../src/routes/(content-single)/(non-course)/${TYPE}/`;
const g = new Glob(`${BASE}**/*.md`, {});

const delay = async (ms) => new Promise((res) => setTimeout(res, ms));

const addArticle = async (input) => {
return fetch('https://api.hashnode.com/', {
method: 'POST',
headers: {
authorization: '2b02d999-9e2d-409a-a2b4-7a1bcbbc58d5',
'Content-Type': 'application/json'
},
body: JSON.stringify({
operationName: 'createPublication',
query: `mutation createPublication($input: CreateStoryInput!) {
createPublicationStory(
publicationId: "60242f8180da6c44eadf775b"
input: $input
) {
message
post {
_id
title
slug
}
}
}
`,
variables: {
input: {
isPartOfPublication: {
publicationId: '60242f8180da6c44eadf775b'
},
...input
}
}
})
});
};

for await (const file of g) {
const mdFile = fs.readFileSync(file, { encoding: 'utf8', flag: 'r' });
const { data, content } = await matter(mdFile); // data has frontmatter, code is html
const fm = data;
if (!fm) continue;
// TODO: We might need to add a check on cononical if this page is already in dev.to
if (
fm?.slug &&
fm?.title &&
fm?.cover &&
fm?.published === 'published' &&
new Date(fm?.start) < new Date() &&
!fm?.hasnode
) {
console.log('Adding', { slug: fm?.slug, hashnode: fm?.hasnode });

try {
console.log('addArticle to hasnode');

// const response = await addArticle(

const finalContent = `
Original: https://codingcat.dev/${TYPE}/${fm.slug}
${fm?.spotify ? '%[' + fm.spotify + ']' : ''}
${fm?.youtube ? '%[' + fm.youtube + ']' : ''}
${content}`;
const response = await addArticle({
title: fm.title,
subtitle: fm?.excerpt || '',
slug: `${TYPE}-${fm.slug}`,
contentMarkdown: finalContent,
coverImageURL: fm.cover,
isRepublished: {
originalArticleURL: `https://codingcat.dev/${TYPE}/${fm.slug}`
},
tags: [
{
_id: '56744721958ef13879b94cad',
name: 'JavaScript',
slug: 'javascript'
},
{
_id: '56744722958ef13879b94f1b',
name: 'Web Development',
slug: 'web-development'
},
{
_id: '56744723958ef13879b955a9',
name: 'Beginner Developers',
slug: 'beginners'
}
]
});

console.log('addArticle result:', response.status);
if (response?.error) console.error('error', response.error);
// Get new devto url and update
if (response.status === 201) {
const json = await response.json();
if (json?.url) {
console.log('Updating', file, { devto: json.url });
const newMdFile = matter.stringify(content, {
...data,
devto: json.url
});
fs.writeFileSync(file, newMdFile, { encoding: 'utf8' });
}
}
// Avoid 429
await delay(process.env?.SYNDICATE_DELAY ? Integer(process.env.SYNDICATE_DELAY) : 10000);
} catch (error) {
console.error(error);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ excerpt: How you can easily test Angular 17 components with Cypress
hashnode:
published: published
start: November 11, 2023
slug: angular-17-cypress-testing
title: How to test Angular 17 using Cypress.io
youtube: https://youtu.be/w3smSGP4w1M
---
Expand Down

2 comments on commit 8cbe7c1

@vercel
Copy link

@vercel vercel bot commented on 8cbe7c1 Dec 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 8cbe7c1 Dec 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

codingcat-dev – ./apps/codingcatdev

codingcat-dev-git-main-coding-cat-dev.vercel.app
codingcat-dev-coding-cat-dev.vercel.app
codingcat.dev

Please sign in to comment.