Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/tweet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Tweet New Posts

on:
push:
branches: [main]
paths:
- "content/*/module.md"

jobs:
tweet:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Find new blog posts
id: changed
run: |
changed=$(git diff --name-only --diff-filter=A ${{ github.event.before }}..${{ github.sha }} -- 'content/*/module.md' | grep -v '^content/docs' || true)
echo "files<<EOF" >> "$GITHUB_OUTPUT"
echo "$changed" >> "$GITHUB_OUTPUT"
echo "EOF" >> "$GITHUB_OUTPUT"

- name: Tweet new posts
if: steps.changed.outputs.files != ''
env:
X_API_KEY: ${{ secrets.X_API_KEY }}
X_API_SECRET: ${{ secrets.X_API_SECRET }}
X_ACCESS_TOKEN: ${{ secrets.X_ACCESS_TOKEN }}
X_ACCESS_TOKEN_SECRET: ${{ secrets.X_ACCESS_TOKEN_SECRET }}
run: |
echo "${{ steps.changed.outputs.files }}" | while IFS= read -r file; do
if [[ -z "$file" ]]; then continue; fi
if [[ ! -f "$file" ]]; then
echo "Skipping $file — file does not exist"
continue
fi
slug=$(basename "$(dirname "$file")")
tweet_field=$(awk '/<details>/{f=1;next} /<\/details>/{if(f)exit} f' "$file" | grep '^tweet:' | head -1)
if [[ -z "$tweet_field" ]]; then
echo "Skipping $slug — no tweet field"
continue
fi
echo "Tweeting for: $slug"
./marketing/tweet.sh "$slug"
done
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
public/
.DS_Store
.envrc
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM golang:1.25 AS builder
RUN go install github.com/gopherguides/hype/cmd/hype@main
RUN go install github.com/gopherguides/hype/cmd/hype@v0.8.0

FROM golang:1.25
COPY --from=builder /go/bin/hype /usr/local/bin/hype
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build serve dev clean
.PHONY: build serve dev clean tweet tweet-dry

build:
hype blog build
Expand All @@ -17,3 +17,9 @@ docker-build:

docker-run:
docker run -p 3000:3000 hypemd-dev

tweet:
@./marketing/tweet.sh $(SLUG)

tweet-dry:
@./marketing/tweet.sh --dry-run $(SLUG)
2 changes: 1 addition & 1 deletion config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ baseURL: "https://hypemd.dev"
author:
name: "Gopher Guides"
email: ""
twitter: ""
twitter: "@hype_markdown"
theme: "developer"
highlight:
style: "monokai"
Expand Down
2 changes: 2 additions & 0 deletions content/ai-authoring-workflow/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
slug: ai-authoring-workflow
published: 03/15/2026
author: Cory LaNou
author_twitter: @corylanou
seo_description: Learn how to combine AI coding assistants like Claude with Hype's build-time validation to write technical documentation faster while keeping every code example correct.
tags: tutorial, ai, authoring, workflow, claude, hype
tweet: AI can write docs fast, but how do you trust the code examples? Combine Claude with Hype's build-time validation — every snippet is verified before publish.
</details>

AI assistants are transforming how we write code. But when it comes to technical documentation, there's a trust problem: AI can generate plausible-looking code examples that don't actually work. Hype solves this by validating everything at build time — making AI-generated content trustworthy through automated verification.
Expand Down
2 changes: 2 additions & 0 deletions content/deploying-with-docker/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
slug: deploying-with-docker
published: 03/15/2026
author: Cory LaNou
author_twitter: @corylanou
seo_description: Deploy a Hype-powered blog site with Docker. Covers Dockerfile setup, Dokploy, Heroku, and generic VPS deployment with Docker Compose.
tags: tutorial, docker, deployment, blog, hype
tweet: Deploy a Hype-powered blog with Docker — from Dockerfile to production. Covers Dokploy, Heroku, and Docker Compose setups.
</details>

Hype builds and serves your blog in a single binary. That makes it a natural fit for Docker — one container that builds your site from source and serves it, with no external web server required.
Expand Down
2 changes: 2 additions & 0 deletions content/engineering-handbook/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
slug: engineering-handbook
published: 03/15/2026
author: Cory LaNou
author_twitter: @corylanou
seo_description: Use Hype to build an internal engineering handbook that stays in sync with your codebase. Executable examples, automated validation, and single-source documentation for your team.
tags: tutorial, engineering, handbook, automation, hype
tweet: Your engineering handbook is probably wrong. Not because it was written badly — the code just changed. Here's how to make docs a build artifact with Hype.
</details>

Every engineering team has internal documentation. Style guides, onboarding docs, architecture decision records, runbook procedures. And almost universally, that documentation is wrong. Not because someone wrote it badly, but because the code changed and nobody updated the docs.
Expand Down
2 changes: 2 additions & 0 deletions content/getting-started/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
slug: getting-started
published: 03/15/2026
author: Gopher Guides
author_twitter: @hype_markdown
seo_description: Learn how to install Hype, create your first dynamic Markdown document, and execute code blocks at build time.
tags: tutorial, getting-started, hype
tweet: What if your Markdown could execute code and catch errors before you publish? Get started with Hype — dynamic Markdown for Go developers.
</details>

Hype is a content engine that makes Markdown dynamic. You can execute code, include files, and validate everything at build time. This guide walks you through installation and your first hype document.
Expand Down
2 changes: 2 additions & 0 deletions content/release-notes-pipeline/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
slug: release-notes-pipeline
published: 03/15/2026
author: Cory LaNou
author_twitter: @corylanou
seo_description: Build a release notes pipeline using Hype with executable code snippets, automated validation, and version-aware documentation that ships with every release.
tags: tutorial, release-notes, ci-cd, pipeline, hype
tweet: Bad release notes erode trust. Build a pipeline where every code example compiles, every command runs, and every API ref is verified at build time.
</details>

Release notes are the first thing users read after updating. Bad release notes — outdated examples, broken migration commands, incorrect API signatures — erode trust and generate support tickets. Hype lets you build release notes where every code example compiles, every command runs, and every API reference reflects the actual release.
Expand Down
2 changes: 2 additions & 0 deletions content/single-source-docs/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
slug: single-source-docs
published: 03/15/2026
author: Cory LaNou
author_twitter: @corylanou
seo_description: Learn how to use Hype to maintain a single Markdown source that generates both your GitHub README and website documentation, keeping them permanently in sync.
tags: tutorial, docs, workflow, hype
tweet: Your README says one thing, your docs site says another. Write it once with Hype and generate both from a single source.
</details>

Every open source project has the same problem: documentation lives in too many places. Your README says one thing, your docs site says another, and the install instructions in your wiki are three versions behind. You end up maintaining the same content in multiple locations, and they inevitably drift apart.
Expand Down
2 changes: 2 additions & 0 deletions content/training-materials/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
slug: training-materials
published: 03/15/2026
author: Cory LaNou
author_twitter: @corylanou
seo_description: Learn how to use Hype to build reusable training and course materials with executable code examples, file includes, and modular content that stays in sync with your codebase.
tags: tutorial, training, education, includes, hype
tweet: Training materials go stale the moment code changes. Use Hype to build courses with executable examples that stay in sync with your codebase.
</details>

If you've ever written training materials for a programming course, you know the pain: code examples go stale, exercises drift out of sync with the slides, and updating one module means checking every other module that references it. Hype was built to solve exactly this problem.
Expand Down
91 changes: 91 additions & 0 deletions marketing/SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# X/Twitter API Setup

## 1. Create an X Developer Account

1. Go to https://developer.x.com and sign in with the @hype_markdown account
2. Sign up for the **Free** tier (1,500 tweets/month, write-only)
3. Create a new **Project** and **App**

## 2. Configure App Permissions

1. In your app settings, go to **User authentication settings**
2. Set app permissions to **Read and Write**
3. After changing permissions, **regenerate** your Access Token and Access Token Secret (old tokens won't have the new permissions)

## 3. Generate Credentials

From your app's **Keys and Tokens** page, you need 4 values:

| Credential | Environment Variable |
|-----------|---------------------|
| API Key (Consumer Key) | `X_API_KEY` |
| API Secret (Consumer Secret) | `X_API_SECRET` |
| Access Token | `X_ACCESS_TOKEN` |
| Access Token Secret | `X_ACCESS_TOKEN_SECRET` |

## 4. Local Setup

Copy the credentials into `.envrc` at the project root:

```bash
export X_API_KEY="your-api-key"
export X_API_SECRET="your-api-secret"
export X_ACCESS_TOKEN="your-access-token"
export X_ACCESS_TOKEN_SECRET="your-access-token-secret"
```

Then activate with direnv:

```bash
direnv allow
```

Test with a dry run:

```bash
make tweet-dry SLUG=getting-started
```

## 5. CI Setup (GitHub Actions)

Set the repository secrets using the `gh` CLI:

```bash
gh secret set X_API_KEY --body "your-api-key"
gh secret set X_API_SECRET --body "your-api-secret"
gh secret set X_ACCESS_TOKEN --body "your-access-token"
gh secret set X_ACCESS_TOKEN_SECRET --body "your-access-token-secret"
```

Once set, the `tweet.yml` workflow will automatically tweet when blog posts with a `tweet` field are merged to main.

## 6. Manual Tweeting

To tweet an existing post manually:

```bash
make tweet SLUG=getting-started
```

To preview without posting:

```bash
make tweet-dry SLUG=getting-started
```

## Adding Tweets to Blog Posts

Add a `tweet` field to the `<details>` frontmatter block in any blog post:

```markdown
<details>
slug: my-article
published: 03/16/2026
author: Gopher Guides
seo_description: Full SEO description here
tags: tutorial, hype
tweet: Short punchy text for X (max ~250 chars, URL is appended automatically)
</details>
```

The script automatically appends the post URL, so keep the tweet text under ~250 characters.
Loading
Loading