I recently joined Dev.to and wanted to automate my article publishing directly from GitHub. However, I quickly hit a roadblock: I wanted to publish posts under an Organization, but I realized I had to write a custom script using the Forem API to make that happen, as existing tools didn’t fully support it.
I started writing a custom GitHub Action just for my own workflow. But halfway through, I thought, “Why not just make this available for everyone on the GitHub Marketplace?” And so, Publish to Dev.to Organization Action was born!
But of course, before publishing a tool that interacts with a live API, I needed a way to test it thoroughly. If you test a publishing workflow live, you risk spamming your followers or hitting rate limits.
To solve this, I implemented a dry_run feature in this action. In this post, I’ll show you how to use this feature to test all 8 possible publishing patterns without making any actual publishing API calls (POST or PUT) to Dev.to. (Note: The action only makes safe GET requests to resolve Organization IDs when necessary.)
The 8-Pattern Matrix
When managing Dev.to articles via front matter, there are 3 variables that create 8 unique scenarios:
- Target: Personal Account vs. Organization
- State: Draft (
published: false) vs. Public (published: true) - Action: Create (
POST) vs. Update (PUT)
You can test all of these in two simple rounds using GitHub Actions.
Prerequisites: The Workflow Setup
First, set up your workflow using tj-actions/changed-files to only process modified files, and enable dry_run: 'true' in this custom action.
# .github/workflows/publish.yml
name: Publish to Dev.to
on:
push:
branches:
- main
paths:
- 'posts/**.md'
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v47
with:
files: posts/*.md
- name: Publish Articles
if: steps.changed-files.outputs.any_changed == 'true'
uses: tinyalg/publish-devto-org-action@v1
with:
devto_api_key: ${{ secrets.DEVTO_API_KEY }}
file_path: ${{ steps.changed-files.outputs.all_changed_files }}
dry_run: 'true' # This prevents actual POST/PUT API calls!
- name: Commit Article IDs
if: steps.changed-files.outputs.any_changed == 'true'
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "chore: update Dev.to article IDs [skip ci]"
file_pattern: 'posts/*.md'
Round 1: Testing “Create” (POST)
To test the 4 creation patterns, create the following four markdown files in your posts/ directory.
1. Personal & Draft (pattern1.md)
---
title: Pattern 1 Personal Draft
published: false
---
Test content here.
2. Personal & Published (pattern2.md)
---
title: Pattern 2 Personal Published
published: true
---
Test content here.
3. Organization & Draft (pattern3.md)
---
title: Pattern 3 Org Draft
published: false
organization_username: tinyalg
---
Test content here.
4. Organization & Published (pattern4.md)
---
title: Pattern 4 Org Published
published: true
organization_username: tinyalg
---
Test content here.
After committing and pushing these files, check your GitHub Actions logs. You will see the dry_run output. The action simulates the API, confirms it would have sent a POST request, and injects a mock id (e.g., id: 9123456) into each file. The git-auto-commit step then saves this back to your repo.
Round 2: Testing “Update” (PUT)
Now that the files have an id assigned to them, you can test the update patterns.
- Run
git pullon your local machine to fetch the mock IDs added by the GitHub Action. - Open the 4 files and make a tiny change (e.g., add a new line at the bottom).
- Commit and push again.
Check the GitHub Actions logs once more. Because the files now contain an id in their front matter, the action correctly identifies them as existing articles. You will see that it would have executed a PUT request to https://dev.to/api/articles/<mock-id>.
Conclusion
And just like that, you’ve tested your entire CI/CD publishing pipeline—including file diffing, ID injection, and payload generation—without publishing a single test post to your actual Dev.to feed!
Once you are confident, simply remove dry_run: 'true' from your workflow, and you are ready to automate your Dev.to blog.
Feel free to check out the action here: Publish to Dev.to Organization Action
Happy automating! 🚀