feat: exclude scheduled posts and links

feat: automatically deploy scheduled posts or links
This commit is contained in:
Ze Bateira
2021-04-16 18:16:40 +01:00
parent 872ad1e63e
commit 1a9338d00b
10 changed files with 189 additions and 18 deletions
@@ -0,0 +1,26 @@
name: Check for scheduled posts to publish
on:
schedule:
- cron: '* 9,21 * * *'
jobs:
check-n-publish:
name: Check for scheduled posts and publish if any found
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Install dependencies
run: npm ci
- name: Check for scheduled posts
run: echo "::set-output name=should_publish::$(${{ github.workspace }}/scripts/scheduled-publishing.js)"
id: should_publish_step
- name: Trigger Fleek Build
if: ${{ steps.should_publish_step.outputs.should_publish == 'true' }}
id: deploy
uses: fleekhq/action-deploy@v1
with:
apiKey: ${{ secrets.FLEEK_API_KEY }}
- name: Scheduled posts published
if: ${{ steps.should_publish_step.outputs.should_publish == 'true' }}
run: echo "Check https://blog.ipfs.io"
+2
View File
@@ -33,6 +33,7 @@
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^7.9.0",
"gray-matter": "^4.0.2",
"husky": "^6.0.0",
"lint-staged": "^10.5.4",
"lodash": "^4.17.21",
@@ -41,6 +42,7 @@
"markdown-it-task-lists": "^2.1.1",
"markdown-it-video": "^0.6.3",
"npm-run-all": "^4.1.5",
"p-map": "^4.0.0",
"postcss": "^7.0.35",
"prettier": "^2.2.1",
"slug": "^4.0.3",
+2
View File
@@ -30,6 +30,7 @@
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^7.9.0",
"gray-matter": "^4.0.2",
"husky": "^6.0.0",
"lint-staged": "^10.5.4",
"lodash": "^4.17.21",
@@ -38,6 +39,7 @@
"markdown-it-task-lists": "^2.1.1",
"markdown-it-video": "^0.6.3",
"npm-run-all": "^4.1.5",
"p-map": "^4.0.0",
"postcss": "^7.0.35",
"prettier": "^2.2.1",
"slug": "^4.0.3",
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env node
'use strict'
/**
* Scheduled Publishing of posts and links.
* This script checks for any blog posts and links that are scheduled to
* be published, but are to be published today. If there is at least
* one found, a build is trigged in fleek, updating the website
* with the latest data.
*/
const fs = require('fs')
const path = require('path')
const pMap = require('p-map')
const matter = require('gray-matter')
const dayjs = require('dayjs')
const isBetween = require('dayjs/plugin/isBetween')
dayjs.extend(isBetween)
async function main() {
// read files contents concurrently, 10 at a time
const contentDir = path.resolve(__dirname, '../src/_blog')
const files = await pMap(
await fs.promises.readdir(contentDir),
(filename) => {
if (!filename.endsWith('.md')) {
return null
}
return fs.promises.readFile(path.resolve(contentDir, filename), 'utf8')
},
{ concurrency: 10 }
)
const output = files
// exclude possible nulls
.filter((result) => !!result)
// process files into publishable items (posts or links)
.reduce((items, fileContent) => {
const metadata = matter(fileContent).data
if (metadata.type && metadata.data) {
// links
items.push(...metadata.data)
} else {
items.push(metadata)
}
return items
}, [])
// check if there is at least one publish date in the future
.some((item) => {
let publishDate
// blog post
if (item.permalink) {
publishDate = item.date
}
// links
if (item.url && item.publish_date) {
publishDate = item.publish_date
}
if (!publishDate) {
return false
}
// we trim to the hour to avoid counting the initial delays on triggering
// the job, which could cause the time calculations to exclude specific
// scheduled dates and times.
const now = dayjs(new Date()).startOf('hour')
const timeMatch = dayjs(new Date(publishDate)).isBetween(
now.subtract(12, 'hour'),
now
)
// using stderr since stdout is used for GH workflow output
if (timeMatch) {
console.error(`Found post/link to publish: "${item.title}"`)
}
return timeMatch
})
if (!output) {
console.error('Nothing found to publish.')
}
// output true or false: should trigger publish or not
// GH Workflow step reads from stdout
console.log(output)
}
main()
+42 -2
View File
@@ -1,4 +1,32 @@
const slug = require('slug')
const dayjs = require('dayjs')
function shouldBeHidden(frontmatter) {
const isDateInFuture = (date) => dayjs(new Date(date)).isAfter(dayjs())
let shouldHide = frontmatter.hidden || false
// sitemap config
if (frontmatter.sitemap) {
shouldHide = shouldHide || frontmatter.sitemap.exclude
}
// scheduled posts
// see auto-publishing of scheduled posts here: https://github.com/ipfs/ipfs-blog/issues/147
if (
!shouldHide &&
frontmatter.permalink && // permalink is unique to posts
frontmatter.date
) {
shouldHide = shouldHide || isDateInFuture(frontmatter.date)
}
// scheduled links (path is unique to links)
if (!shouldHide && frontmatter.path && frontmatter.publish_date) {
shouldHide = shouldHide || isDateInFuture(frontmatter.publish_date)
}
return shouldHide
}
module.exports = (options, context) => ({
extendPageData($page) {
@@ -18,8 +46,8 @@ module.exports = (options, context) => ({
frontmatter.authorKey = authorKey
}
// exclude a page from the feed & robots if excluded from sitemap
if (frontmatter.sitemap && frontmatter.sitemap.exclude) {
// exclude hidden pages (sitemap config, future publishes, etc)
if (shouldBeHidden(frontmatter)) {
frontmatter.feed = {
enable: false,
}
@@ -30,6 +58,18 @@ module.exports = (options, context) => ({
} else {
frontmatter.meta = [noIndex]
}
frontmatter.hidden = true
$page.hidden = true
}
// set links has hidden (future publishes, etc)
if (frontmatter.data) {
frontmatter.data.forEach((item) => {
if (shouldBeHidden(item)) {
item.hidden = true
}
})
}
},
})
+2 -8
View File
@@ -128,14 +128,8 @@ export default {
return false
}
if (
page.frontmatter &&
(page.frontmatter.sitemap ? !page.frontmatter.sitemap.exclude : true)
) {
result.push({
...page,
category: defaultCategory,
})
if (page.frontmatter && !page.frontmatter.hidden) {
result.push({ ...page, category: defaultCategory })
}
})
+12 -1
View File
@@ -1,5 +1,5 @@
<template>
<Layout v-if="!$frontmatter.type">
<Layout v-if="isVisible">
<article itemscope itemtype="https://schema.org/BlogPosting">
<PostHero
:title="$page.title"
@@ -46,7 +46,18 @@ export default {
data: () => ({
showComments: null,
}),
computed: {
// hidden field set in plugins/pageData.js
isVisible() {
return !this.$root.$page.hidden
},
},
mounted() {
if (!this.isVisible) {
// path to 404 is relative to support ipfs sub path deployments
return this.$router.replace({ path: '../404' })
}
const ipfsPathRegExp = /^(\/(?:ipfs|ipns)\/[^/]+)/
const ipfsPathPrefix =
(window.location.pathname.match(ipfsPathRegExp) || [])[1] || ''
+5 -4
View File
@@ -1,4 +1,4 @@
export const checkItem = ({
export function checkItem({
postType,
tags,
title,
@@ -7,7 +7,7 @@ export const checkItem = ({
searchedText = [],
activeCategory = '',
activeAuthor = '',
}) => {
}) {
if (activeCategory && decodeURI(activeCategory) !== postType) {
return false
}
@@ -40,13 +40,13 @@ export const checkItem = ({
return true
}
export const parseProtectedPost = (
export function parseProtectedPost(
post,
activeTags = [],
searchedText = [],
activeCategory = '',
activeAuthor = ''
) => {
) {
if (!post.frontmatter.data) {
return []
}
@@ -55,6 +55,7 @@ export const parseProtectedPost = (
post.frontmatter.data.forEach((item) => {
if (
item.hidden ||
!checkItem({
postType: post.frontmatter.type,
tags: item.tags,
-2
View File
@@ -6,7 +6,6 @@ sitemap:
data:
- title: IPFS Community Meetup, April 2021
date: 2021-04-27
publishing_date:
path: https://www.meetup.com/San-Francisco-IPFS/events/276123324/
card_image: "/2021-04-15-cardheader-ipfs-meetup-nft-april2021.png"
tags:
@@ -14,7 +13,6 @@ data:
- official meetup
- title: Cal Hacks hello:world
date: 2021-04-16
publishing_date: 2021-04-15 17:06:47 +0000
path: https://helloworld.calhacks.io/
card_image: "/2021-04-15-cardheader-hello-world.png"
tags:
-1
View File
@@ -1,5 +1,4 @@
---
publishing_date:
title: Welcome to IPFS Weekly 131
description: Uniswap Interface hosting on IPFS, a call for Filecoin user testers,
and more from around the ecosystem!