Skip to content

Commit

Permalink
Merge pull request #75 from OUCC/ci-fix-update-blogmeta
Browse files Browse the repository at this point in the history
Update actions/checkout from v3 to v4 and fix update-blogmeta
  • Loading branch information
miyaji255 authored Dec 12, 2023
2 parents 170cb6d + f6b28c9 commit 5097f27
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 83 deletions.
42 changes: 23 additions & 19 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
build:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
Expand All @@ -28,7 +28,7 @@ jobs:
lint:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
Expand All @@ -39,7 +39,7 @@ jobs:
typecheck:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
Expand All @@ -52,42 +52,46 @@ jobs:
needs: [build, lint, typecheck]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
cache: npm
- run: npm ci
- run: git diff origin/main..HEAD --name-only | xargs npm run validate-blog --
- run: |
git fetch origin main
git diff origin/main..HEAD --name-only | xargs npm run validate-blog --
update-blogmeta:
needs: [validate-blog]
permissions:
contents: write
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Checkout pull request HEAD commit instead of merge commit
with:
ref: ${{ github.event.pull_request.head.ref }}
- uses: actions/setup-node@v3
with:
node-version-file: .node-version
cache: npm
- run: npm ci
- name: Update blog meta
id: update_blogmeta
- name: Update Blog Meta
run: |
git diff origin/main..HEAD --name-only | xargs npm run update-blogmeta --
echo "{UPDATE_RESULT}_{$?}" >> "$GITHUB_OUTPUT"
continue-on-error: true
- run: exit ${{ steps.update_blogmeta.outputs.UPDATE_RESULT }}
if: steps.update_blogmeta.outputs.UPDATE_RESULT != '1' && steps.update_blogmeta.outputs.UPDATE_RESULT != '0'
git fetch origin main
git diff origin/main..HEAD --name-status | xargs npm run update-blogmeta --
- name: Git Commit
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add .
git commit -m "[Bot] Update blog meta"
git push origin ${{github.head_ref}}
if: steps.update_blogmeta.outputs.UPDATE_RESULT == '0'
git add -N .
if ! git diff --exit-code --quiet
then
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add .
git commit -m "[Bot] Update Blog Meta"
git push
fi
deploy:
if: github.ref == 'refs/heads/main'
Expand Down
159 changes: 134 additions & 25 deletions tools/update-blogmeta.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,171 @@
import * as fs from 'fs'
import * as path from 'path'

const ok = validateExistingFiles()
if (!ok) process.exit(2)
updateBlogMeta()
type FileStatus =
| [status: 'A' | 'C' | 'D' | 'M' | 'T', path: string]
| [status: `R${number}`, fromPath: string, toPath: string]

type BlogMeta = {
postDate: string
updateDate?: string
}
const gitDiffs = validateArgs(chunkArray(process.argv.slice(2), 2))
if (gitDiffs === null) process.exit(1)
updateBlogMeta(gitDiffs)

function validateExistingFiles() {
function validateArgs(gitDiffs: string[][]): FileStatus[] | null {
let ok = true
for (const file of process.argv.slice(2)) {
if (!fs.existsSync(file) || !fs.statSync(file).isFile()) {
console.log(`\u001b[31m[ERROR]\tThe file was not found: ${file}\u001b[m`)
function validateFile(path: string) {
if (!fs.existsSync(path) || !fs.statSync(path).isFile()) {
console.log(`\u001b[31m[ERROR]\tThe file was not found: ${path}\u001b[m`)
ok = false
return false
}
return true
}
return ok

const result: FileStatus[] = []

for (const status of gitDiffs) {
if (status.length != 2 && status.length != 3) {
console.log(
`\u001b[31m[ERROR]\tArgument is invalid format.\n Please set results of \`git diff --name-status\`. \u001b[m`,
)
ok = false
continue
}

if (status.length === 2) {
if (!['A', 'C', 'D', 'M', 'T'].includes(status[0]!)) {
console.log(
`\u001b[33m[WARNING]\tThe status does not supported: ${status[0]}\t${status[1]}\u001b[m`,
)
continue
}

if (status[0] === 'D' || validateFile(status[1]!)) {
result.push(status as ['A' | 'C' | 'D' | 'M' | 'T', string])
}
} else if (status.length === 3) {
if (
status[0]!.startsWith('R') &&
Number.isInteger(Number(status[0]!.slice(1)))
) {
if (validateFile(status[1]!) && validateFile(status[2]!)) {
result.push(status as [`R${number}`, string, string])
}
} else
console.log(
`\u001b[33m[WARNING]\tThe status does not supported: ${status[0]}\t${status[1]}\u001b[m`,
)
}
}
return ok ? result : null
}

/**
* blog meta のファイルの日付を更新します
*/
function updateBlogMeta() {
const targetFiles = process.argv
.slice(2)
.map(path.parse)
.filter(
(parsedPath) =>
parsedPath.dir === 'src/content/blogs' && parsedPath.ext === '.md',
function updateBlogMeta(gitDiffs: readonly FileStatus[]) {
const targetFiles = gitDiffs
.map(([status, filePath, toPath]) =>
toPath === undefined
? ([status, path.parse(filePath)] as const)
: ([status, path.parse(toPath)] as const),
)
if (targetFiles.length === 0) {
console.log(
'\u001b[31m[ERROR]\tSet more than one target files to args.\u001b[m',
)
process.exit(1)
}
.filter(predicateTargetFiles)
const updatedMetas = gitDiffs
.map(([status, filePath, toPath]) => [status, toPath ?? filePath] as const)
.filter(([status, filePath]) => {
const { dir, ext } = path.parse(filePath)
return (
status !== 'D' && dir === 'src/content/blog-metas' && ext === '.json'
)
})

for (const [_, { dir, name, ext }] of targetFiles) {
const updatedName =
ext === '.md' || ext === '.mdx'
? name
: dir.slice('src/content/blogs/'.length).split('/')[0]!

for (const { dir, name } of targetFiles) {
const blogMetaPath = path.resolve(dir, `./blog-meta/${name}.json`)
const blogMetaPath = `src/content/blog-metas/${updatedName}.json`

let meta: BlogMeta | null = null
if (fs.existsSync(blogMetaPath)) {
meta = JSON.parse(
fs.readFileSync(blogMetaPath, { encoding: 'utf-8' }),
) as BlogMeta

meta.updateDate = new Date().toISOString()
if (updatedMetas.every(([_, filePath]) => filePath !== blogMetaPath))
meta.updateDate = new Date().toISOString()
else {
// 今回のPRで既に更新済み

if (meta.updateDate) meta.updateDate = new Date().toISOString()
else meta.postDate = new Date().toISOString()
}
} else {
meta = {
postDate: new Date().toISOString(),
}
}

fs.writeFileSync(blogMetaPath, JSON.stringify(meta, undefined, 2))
fs.writeFileSync(blogMetaPath, JSON.stringify(meta, undefined, 2) + '\n')

console.log(`[INFO]\tUpdate blog meta: ${blogMetaPath}`)
}
}

function predicateTargetFiles([status, file]: readonly [
'A' | 'C' | 'D' | 'M' | 'T' | `R${number}`,
path.ParsedPath,
]): boolean {
// markdown
if (
(['A', 'C', 'M', 'T'].includes(status) || status.startsWith('R')) &&
file.dir === 'src/content/blogs' &&
(file.ext === '.md' || file.ext === '.mdx')
)
return true

// 画像
if (
(['A', 'C', 'D', 'M', 'T'].includes(status) || status.startsWith('R')) &&
file.dir.startsWith('src/content/blogs/') &&
[
'.jpg',
'.jpeg',
'.jfif',
'.pjpeg',
'.pjp',
'.png',
'.svg',
'.webp',
'.gif',
'.avif',
'.apng',
].includes(file.ext)
)
return true

return false
}

function chunkArray<T>(array: T[], chunkSize: number) {
const result: T[][] = []
let tempArray: T[] = []
for (const val of array) {
if (tempArray.length < chunkSize) {
tempArray.push(val)
} else {
result.push(tempArray)
tempArray = [val]
}
}

if (tempArray.length !== 0) {
result.push(tempArray)
}
return result
}
67 changes: 28 additions & 39 deletions tools/validate-blog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ process.exit(validateBlog() ? 0 : 1)
* 変更されたファイルが許可されているものに含まれているか判定します
*
* 許可されているファイルは以下のとおりです。
* - src/content/blogs/*.md (blogs, tags, authors 以外)
* - src/content/blogs/*.{md, mdx}
* - src/content/blogs/ より一階層下にある画像
* - src/content/authors/*.json
* - src/content/blog-metas/*.json (blogs, tags, authors 以外)
* - src/content/authors/ にある画像
* - src/content/blog-metas/*.json
* - src/content/tags/*.json
* - src/assets/icons/blog/*.svg
* - src/content/tags/ にある画像
*/
function validateBlog() {
let ok = true
Expand All @@ -21,48 +22,20 @@ function validateBlog() {

if (parsedPath.dir === 'src/content/blogs') {
// ブログ本体
if (
parsedPath.ext === '.md' &&
!['blogs', 'tags', 'authors'].includes(parsedPath.name)
)
continue
if (parsedPath.ext === '.md' || parsedPath.ext === '.mdx') continue
} else if (parsedPath.dir === 'src/content/blog-metas') {
// ブログのメタ情報
if (
parsedPath.ext === '.json' &&
!['blogs', 'tags', 'authors'].includes(parsedPath.name)
)
continue
} else if (parsedPath.dir.startsWith('src/content/blogs/')) {
// 画像
if (
[
'.jpg',
'.jpeg',
'.jfif',
'.pjpeg',
'.pjp',
'.png',
'.svg',
'.webp',
'.gif',
'.avif',
'.apng',
].includes(parsedPath.ext)
)
continue
if (parsedPath.ext === '.json') continue
} else if (
// ブログの著者・タグ
['src/content/authors', 'src/content/tags'].includes(parsedPath.dir) &&
parsedPath.ext === '.json'
parsedPath.dir.match(/^src\/content\/blogs\/[^(#/)]*\/[^(#/)]*$/)
) {
continue
// 画像
if (isImage(parsedPath.ext)) continue
} else if (
// ブログのアイコン
parsedPath.dir === 'src/assets/icons/blog' &&
parsedPath.ext === '.svg'
['src/content/authors', 'src/content/tags'].includes(parsedPath.dir)
) {
continue
// ブログの著者・タグ
if (parsedPath.ext === '.json' || isImage(parsedPath.ext)) continue
}

console.log(
Expand All @@ -73,3 +46,19 @@ function validateBlog() {

return ok
}

function isImage(ext: string) {
return [
'.jpg',
'.jpeg',
'.jfif',
'.pjpeg',
'.pjp',
'.png',
'.svg',
'.webp',
'.gif',
'.avif',
'.apng',
].includes(ext)
}

0 comments on commit 5097f27

Please sign in to comment.