Compare commits

..

No commits in common. "600bddab7cd7dc6e4032b531c65779ae249dfd5b" and "5ddbcd3da9c649ceda29796f601cf550339424d6" have entirely different histories.

8 changed files with 339 additions and 817 deletions

View file

@ -6,7 +6,7 @@ updates:
- package-ecosystem: npm
directory: /
schedule:
interval: monthly
interval: weekly
day: friday
time: "18:00"
timezone: Asia/Bangkok
@ -24,7 +24,7 @@ updates:
- package-ecosystem: gomod
directory: /
schedule:
interval: monthly
interval: weekly
day: friday
time: "18:00"
timezone: Asia/Bangkok
@ -42,7 +42,7 @@ updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: monthly
interval: weekly
day: friday
time: "18:00"
timezone: Asia/Bangkok

View file

@ -1,162 +0,0 @@
import { readFile, writeFile, access, mkdir } from 'node:fs/promises';
import path from 'node:path';
import fs from 'node:fs';
import dotenv from 'dotenv';
import { homedir } from 'node:os';
const userHomeDir = homedir();
// Load .env files
const GLOBAL_ENV_PATH = path.join(userHomeDir, '.env');
const LOCAL_ENV_PATH = path.resolve('.env');
/**
* Load environment variables from a file if it exists.
* @param {string} filePath
* @returns {object} Parsed environment variables
*/
function loadEnvFile(filePath) {
if (fs.existsSync(filePath)) {
return dotenv.parse(fs.readFileSync(filePath));
}
return {};
}
// Merge global and local .env configurations
const globalEnv = loadEnvFile(GLOBAL_ENV_PATH);
const localEnv = loadEnvFile(LOCAL_ENV_PATH);
process.env = { ...globalEnv, ...process.env, ...localEnv };
// Configurable values
const DISCORD_WEBHOOK = process.env.DISCORD_WEBHOOK || '';
const GITHUB_DEV_TOKEN = process.env.GITHUB_DEV_TOKEN || '';
const GITHUB_REPO = process.env.GITHUB_REPO || 'theNewDynamic/gohugo-theme-ananke';
const DEFAULT_MESSAGE_TEMPLATE = 'New release: {{tag_name}} - {{html_url}}';
const MESSAGE_TEMPLATE = process.env.MESSAGE_TEMPLATE || DEFAULT_MESSAGE_TEMPLATE;
const CACHE_DIR = './cache';
const CACHE_FILE = 'github-releases.json';
const CACHE_FILE_PATH = path.join(CACHE_DIR, CACHE_FILE);
/**
* Ensures the cache directory exists, creating it if necessary.
* @returns {Promise<void>}
*/
async function ensureCacheDirectory() {
try {
await access(CACHE_DIR);
} catch {
try {
await mkdir(CACHE_DIR, { recursive: true });
} catch (err) {
console.error(`Failed to create cache directory: ${err.message}`);
process.exit(1);
}
}
}
/**
* Reads the cache file or returns an empty array if not found.
* @returns {Promise<string[]>}
*/
async function readCache() {
try {
const data = await readFile(CACHE_FILE_PATH, 'utf8');
return JSON.parse(data) || [];
} catch {
return [];
}
}
/**
* Writes data to the cache file.
* @param {string[]} data
*/
async function writeCache(data) {
await writeFile(CACHE_FILE_PATH, JSON.stringify(data, null, 2));
}
/**
* Fetches the latest release from the GitHub REST API.
* @returns {Promise<{ tag_name: string, html_url: string } | null>}
*/
async function fetchLatestRelease() {
try {
const response = await fetch('https://api.github.com/repos/' + GITHUB_REPO + '/releases', {
headers: {
Authorization: `token ${GITHUB_DEV_TOKEN}`,
},
});
if (!response.ok) {
throw new Error(`GitHub API request failed: ${response.statusText}`);
}
const releases = await response.json();
if (!Array.isArray(releases) || releases.length === 0) {
console.log('No releases found.');
return null;
}
return releases[0];
} catch (err) {
console.error('Failed to fetch releases:', err.message);
return null;
}
}
/**
* Posts a message to Discord using a webhook.
* @param {string} message
*/
async function postToDiscord(message) {
try {
const response = await fetch(DISCORD_WEBHOOK, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: message }),
});
if (!response.ok) {
throw new Error(`Failed to post to Discord: ${response.statusText}`);
}
console.log('Posted to Discord successfully.');
} catch (err) {
console.error('Failed to post to Discord:', err.message);
}
}
/**
* Formats the release message using the template.
* @param {Record<string, string>} releaseData
* @returns {string}
*/
function formatMessage(releaseData) {
return MESSAGE_TEMPLATE.replace(/{{\s*(\w+)\s*}}/g, (_, key) => releaseData[key] || '');
}
/**
* Main function to fetch the latest GitHub release and post it to Discord.
*/
async function main() {
try {
await ensureCacheDirectory();
const cachedIds = await readCache();
const latestRelease = await fetchLatestRelease();
if (latestRelease && !cachedIds.includes(latestRelease.tag_name)) {
const message = formatMessage(latestRelease);
await postToDiscord(message);
cachedIds.push(latestRelease.tag_name);
await writeCache(cachedIds);
} else {
console.log('No new releases to post.');
}
} catch (err) {
console.error('Error:', err.message);
}
}
main();

390
.gitignore vendored
View file

@ -1,365 +1,41 @@
# local ignored files
cache/
# Created by https://www.toptal.com/developers/gitignore/api/hugo,node,linux,macos,windows,phpstorm+all,visualstudiocode,go
# Edit at https://www.toptal.com/developers/gitignore?templates=hugo,node,linux,macos,windows,phpstorm+all,visualstudiocode,go
### Go ###
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
### Hugo ###
# Generated files by hugo
/public/
/resources/_gen/
/assets/jsconfig.json
hugo_stats.json
# Executable may be added to repository
hugo.exe
hugo.darwin
hugo.linux
# Temporary lock file while building
/.hugo_build.lock
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
# OS
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
### Node Patch ###
# Serverless Webpack directories
.webpack/
# Optional stylelint cache
# SvelteKit build / generate output
.svelte-kit
### PhpStorm+all ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### PhpStorm+all Patch ###
# Ignore everything but code style settings and run configurations
# that are supposed to be shared within teams.
.idea/*
!.idea/codeStyles
!.idea/runConfigurations
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# IDEs
.buildpath
.project
.settings/
.build/
.idea/
public/
nbproject/
# Folder config file
[Dd]esktop.ini
# Vagrant
.vagrant/
# Recycle Bin used on file shares
$RECYCLE.BIN/
# FE Setup
.bin/node_modules/
/node_modules/
src/node_modules/
exampleSite/node_modules/
src/npm-debug.log.*
npm-debug.log
/npm-debug.log*
/dist/
/src/client.config.json
/styleguide/
/docs/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
/junit.xml
partials/structure/stylesheet.html
# Windows shortcuts
*.lnk
# Hugo
.hugo_build.lock
resources/_gen/
# End of https://www.toptal.com/developers/gitignore/api/hugo,node,linux,macos,windows,phpstorm+all,visualstudiocode,go
# Build
.wireit
.favorites.json
*.code-workspace
config/gargulus

View file

@ -1,31 +0,0 @@
{
"folders": [
{
"path": "."
},
{
"path": "../gohugo-theme-ananke.wiki"
}
],
"settings": {
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#65c89b",
"activityBar.background": "#65c89b",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#945bc4",
"activityBarBadge.foreground": "#e7e7e7",
"commandCenter.border": "#15202b99",
"sash.hoverBorder": "#65c89b",
"statusBar.background": "#42b883",
"statusBar.foreground": "#15202b",
"statusBarItem.hoverBackground": "#359268",
"statusBarItem.remoteBackground": "#42b883",
"statusBarItem.remoteForeground": "#15202b",
"titleBar.activeBackground": "#42b883",
"titleBar.activeForeground": "#15202b",
"titleBar.inactiveBackground": "#42b88399",
"titleBar.inactiveForeground": "#15202b99"
}
}
}

View file

@ -1,6 +1,3 @@
[ananke]
show_recent_posts = true # show recent posts on the homepage
[ananke.social]
icon_path = "ananke/socials/%s.svg"

View file

@ -4,7 +4,6 @@
</article>
{{/* Define a section to pull recent posts from. For Hugo 0.20 this will default to the section with the most number of pages. */}}
{{ $mainSections := .Site.Params.mainSections | default (slice "post") }}
{{ $show_recent_posts := site.Params.ananke.show_recent_posts }}
{{/* Check to see if the section is defined for ranging through it */}}
{{range ($mainSections)}}
@ -13,7 +12,7 @@
{{/* Create a variable with that section to use in multiple places. */}}
{{ $section := where $.Site.RegularPages "Section" "in" $section_name }}
{{ $section_count := len $section }}
{{ if and ($show_recent_posts) (ge $section_count 1) }}
{{ if ge $section_count 1 }}
<div class="pa3 pa4-ns w-100 w-70-ns center">
{{/* Use $section_name to get the section title. Use "with" to only show it if it exists */}}
{{ with $.Site.GetPage "section" $section_name }}

550
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -33,15 +33,14 @@
],
"dependencies": {
"cssnano": "7.0.6",
"postcss": "8.4.49",
"postcss-preset-env": "10.1.2",
"postcss": "8.4.47",
"postcss-preset-env": "10.0.9",
"tachyons": "4.12.0"
},
"devDependencies": {
"@davidsneighbour/markdownlint-config": "2024.4.12",
"@davidsneighbour/release-config": "2024.4.12",
"@davidsneighbour/tools": "2024.4.12",
"dotenv": "16.4.7"
"@davidsneighbour/markdownlint-config": "^2024.4.6",
"@davidsneighbour/release-config": "2024.4.8",
"@davidsneighbour/tools": "2024.4.6"
},
"scripts": {
"deploy": "cd exampleSite; hugo;",