Manage your dev.to blog posts from a GIT repo and use continuous deployment to auto publish/update them
Maxime

Maxime @maxime1992

About: Software engineer, I've been working with Angular for 6 years now and strive to work more full stack. I publish on dev.to about topics I love around open source, frontend, data privacy, automations.

Location:
France
Joined:
May 31, 2019

Manage your dev.to blog posts from a GIT repo and use continuous deployment to auto publish/update them

Publish Date: Jul 7 '19
942 63

04/2023 UPDATE: While the overall idea of the blog post remains unchanged and is still relevant, I no longer recommend to use Travis. Instead use Github Actions (or if you're not using Github, any other CI runner of your choice). The template repo has been updated to use Github Actions. Feel free to read this blog post to get the main idea but then head over to the template repo for a more up to date step by step guide.


Have you ever wished that you had a monorepo (*1 ) containing all of your dev.to posts on GitHub and once you merge an update into the master branch they would just automatically be updated on dev.to?

1) or multiple repositories, it doesn't matter 😃

Then you'll be pleased with what's coming, otherwise I'll let you know why you might want that in the next section.

Why would I want to put all my blog posts on a git repo?

  • Don't be afraid of messing up one of your articles while editing it
  • Same good practices as when you're developing (format, make commits, have a history of your changes, compare when editing, etc)
  • Use prettier to format the markdown and all the code snippets
  • Let people contribute to your article by creating a PR against it (tired of comments going sideways because of some typos? Just let people know they can make a PR at the end of your blog post)
  • Create code examples close to your blog post and make sure they're correct thanks to Embedme (*1)

*1: Embedme allows you to write code in actual files rather than into a Markdown file and then will inject the code for you where needed.

If you prefer not to use Prettier or Embedme, you can do so by simply removing them but I think it's a nice thing to have!

Is it long to setup?

No more than a few minutes. Probably 3 to 5 minutes top, from scratch to automatically deploying an update on one of your blog posts on dev.to using this new setup 🔥!

Show me how to set it up!

You can choose whether you want to integrate this workflow into an existing repository or using a template I've made to simplify the process of starting from scratch.

In this blog post we will focus on getting started using the template but reading this you'll realise how easy it would be to integrate in your own workflow.

Main steps:

  • 1. Copy the template
  • 2. Create a dev.to token
  • 3. Pass that token to Travis CI
  • 4. Put your blog post(s) into your new repository

1. Copy the template

Go to https://github.com/maxime1992/dev.to and copy the template:

Copy the template repository

Set the name of the repository as you wish and the description too:

Define the name, description and visibility of the repository

(note: if you want to use the free instance of Travis to continuously deploy your blog posts, the repository has to be public)

Once your repository has been generated, you should see something like the following:

Generated repository

2. Create a dev.to token

Go to https://dev.to/settings/account and give a name to the token so you can remember where you're using it:

Generate a dev to token

Keep the page open for now.

3. Pass that token to Travis

Edit: 8th of July 2020

Beeman has written a great post on dev.to to use Github Actions:

The main advantage of Github Actions over Travis is that you can get 2000mn of free time if the repo is private (which should be more than enough!).

While we'll be focusing on how to use Travis as our CI, do check Beeman's article if you prefer to use Github Actions! =)

Go to https://travis-ci.org/account/repositories

As the GitHub repository has just been created, Travis may not see the repo yet. If that's the case, click on the left on the "Sync account" button to force the refresh of your repositories.

Travis sync account and repositories

Once that's done you should be able to find your project and you'll need to click on the toggle button on the right to activate it:

Travis activate the repository

You can now click on "settings".

We now need to pass the dev.to token to Travis. Within the "environment variables" section, define a new one called DEV_TO_GIT_TOKEN. Go back to the dev.to tab where you've generated the token, copy it and paste it into the "value" input.

Pass the dev to token to Travis

Once ready, click on the "add" button.

4. Put your blog post(s) into your new repository

First thing that you need to do is make sure that your package.json defines a property repository.url. It should look like this one: https://github.com/maxime1992/my-dev.to.git with your own username/repository name. It will be used to retrieve your article images from there.

Then, notice that there's a dev-to-git.json at the root of the project. This is where we will be managing the blog posts we want to publish.

That json file should contain an array, and every entry should have 2 fields: id and relativePathToArticle.

Example:



[
  {
    "id": 133785,
    "relativePathToArticle": "./blog-posts/manage-dev-to-blog-posts-with-continuous-deployment/manage-dev-to-blog-posts-with-continuous-deployment.md"
  }
]


Enter fullscreen mode Exit fullscreen mode

There's no easy way to manage the creation of an article (yet?) but it's a quick / one time thing. Go to https://dev.to and click at the top on the "write a post" button. Write a title (that can be updated later) and press the "Save Draft" button. This way the article is not published yet and only available to you.

As dev.to doesn't display the ID of a blog post on the page itself, I've made a small query to find it into the page. Open your browser console on the dev.to page of your article and paste the following:



+$('div[data-article-id]').getAttribute('data-article-id');


Enter fullscreen mode Exit fullscreen mode

This will give you the ID of the post to put into dev-to-git.json.

Your blog post should have a "front matter" header. For example, the one of the blog post I'm currently writing is:



---
published: false
title: "Manage your dev.to blog posts from a GIT repo and use continuous deployment to auto publish/update them"
cover_image: "https://raw.githubusercontent.com/maxime1992/my-dev.to/master/blog-posts/manage-dev-to-blog-posts-with-continuous-deployment/assets/github-travis-dev-to.png"
description:
tags: devto, publication, blogpost, continuousdeployment, github, travis
series:
canonical_url:
---


Enter fullscreen mode Exit fullscreen mode

This means that you can manage all of those attributes directly from your blog post written in Markdown. How cool is that?

Finally, all the local images links are rewritten to become remote ones that points to the files on GitHub. Yes, even your images can be part of your versioning process 🙌!

Thanks for reading

Don't be shy, let me know what you think of this project in the comments ☺️. Do you like it? Will you consider using it? If not, I'd love to know what's missing to make it work better for you, with your workflow.


I work at CloudNC in central London and we are recruiting!

CloudNC is recruiting

We have a hackday every first Friday of the month and it's during the last one that I decided to work on this project. I've open sourced an npm module called dev-to-git that handles most of the heavy work to read and publish on dev.to (which is used by the template repository).

Found a typo?

If you've found a typo, a sentence that could be improved or anything else that should be updated on this blog post, you can access it through a git repository and make a pull request. Instead of posting a comment, please go directly to https://github.com/maxime1992/my-dev.to and open a new pull request with your changes. If you're interested how I manage my dev.to posts through git and CI, read more here.

Follow me

           
Dev Github Twitter Reddit Linkedin Stackoverflow

You may also enjoy reading

Comments 63 total

  • Louis Augry
    Louis AugryJul 7, 2019

    Good job ! Thank's you for sharing this with us !

    • Maxime
      MaximeJul 8, 2019

      Thanks for the kind words Louis!

  • Areahints
    AreahintsJul 7, 2019

    Wow! learn something new everyday!

  • Carlos Caballero
    Carlos CaballeroJul 7, 2019

    Thanks @maxime1992 , good job!

    • Maxime
      MaximeJul 8, 2019

      Much appreciated Carlos 🙏 thanks!

  • Shijie Zhou
    Shijie ZhouJul 7, 2019

    this way seems like an extra step that you need to make before the post. You always need to get the draft id before it posts.

    • Maxime
      MaximeJul 8, 2019

      It doesn't seem like it is. It clearly is 🙄. Unfortunately it's the best I could come up with as dev.to do not use UUIDs. Otherwise it'd have been easy to generate one 🤷‍♂️ here the only way to automate that part would be to correlate the blog post title but it'd be an issue if you update it (which is obviously not great). As it's a one time thing for an article, I think it's not too bad either though

      • Fyodor
        FyodorJan 12, 2020

        Maxime, first of all, thanks for the cool idea 👍
        I have a couple of questions/suggestions:

        1. (on Jay's concern) Why not try to use dev.to API's POST request and get an article ID with the response?
        2. Didn't you try to replace Travis with Github Actions? This way one gets the opportunity to use the workflow with a private repo
        • Maxime
          MaximeJan 12, 2020

          Hi Fyodor, thanks :)!

          1) It'd be great for sure to have something in command line and we've got an issue here github.com/maxime1992/dev-to-git/i... if you have further ideas on that please share there

          2) I did not as I'm not yet familiar with github actions. I'd be happy to have a PR if you feel like it though! :) Could you please open an issue first there github.com/maxime1992/dev-to-git/i... so we can discuss it and then we can talk about a PR

          Thanks

          • Fyodor
            FyodorJan 13, 2020

            Thanks for the coordination Maxime! Zak's ideas on id handling look comprehensive, they just need to be implemented) As for github actions, I'm not very familiar with that too, need to research, and I would be happy to contribute if I have enough time, you know. Added the issue to discuss further 👌

  • Keiji Matsuzaki
    Keiji MatsuzakiJul 8, 2019

    Good Job! Awesome!!!

  • Pan Wangperawong
    Pan WangperawongJul 8, 2019

    Great job! This allows you to have contributors and editors.

    • Maxime
      MaximeJul 8, 2019

      Definitely a good fit for that use case! 😁

  • Zex
    ZexJul 8, 2019

    what i was thinking about😂 a repo of markdown

  • protium
    protiumJul 8, 2019

    This is a really good idea with great potential. Image a standarized API for different blogs. You can automatize publishing and editing, multiple collaborators. And use a git provider as unique source of content.

    And you can also make your git repo as some sort of blog. I'll use it for my next posts for sure.

    Thanks!

    • Maxime
      MaximeJul 8, 2019

      Hi Brian,

      This is a really good idea with great potential

      Thanks! I do intend to push it further and someone else plans to help me out :)!

      Image a standarized API for different blogs

      That was the original purpose. But I realized it wouldn't fit into a hackday so I decided to get the project up and running with support for only one "publisher" (dev.to). My original though was that I'd build something completely abstract and we could choose for one article to publish on multiple "publisher" at the same time (dev.to, medium, etc).

      And you can also make your git repo as some sort of blog

      Definitely!

      I'll use it for my next posts for sure.

      Awesome, glad to hear that! =)

    • Fernando B 🚀
      Fernando B 🚀Jul 8, 2019

      Check out my git jekyll blog takes less than a few minutes to setup.

      Jekyll

  • Periklis Gkolias
    Periklis GkoliasJul 8, 2019

    Awesome. Just on time I was thinking to setup such thing.

    • Maxime
      MaximeJul 8, 2019

      Awesome Periklis, if you give it a go let me know if you found the setup easy or if there was any pain point 👌

  • Michael Brooks
    Michael BrooksJul 8, 2019

    I've literally just moved my Blog from WP to VuePress and publishing it over to Netlify with NetlifyCMS integrated. I'm going to try and integrate this into workflow and see if it works. Thank you for this blog post.

    • Maxime
      MaximeJul 8, 2019

      Hey Michael,

      Glad you're up to give it a go, let me know how it goes!

  • Priyanka Kore
    Priyanka KoreJul 8, 2019

    Best thing ever!! Thank you so much for sharing 🙌🏻🙌🏻

    • Maxime
      MaximeJul 8, 2019

      Thanks for the kind words Priyanka 😊!

  • Fernando B 🚀
    Fernando B 🚀Jul 8, 2019

    I just started writing my articles on a repo and using Jekyll, with rss feed. Only drawback is once article is released on dev, and changed on repo, it won't update.

  • Maxime
    MaximeJul 8, 2019

    I'm sorry I might be missing something but I do not understand what you mean, could you be more specific?

  • José Coelho
    José CoelhoJul 8, 2019

    What a great idea Maxime! And also a great way to build up your GitHub profile in case you're low on contributions (if some recruiters are looking at your profile)

  • Rom
    RomJul 9, 2019

    Nice, thanks for sharing!

  • Michael M. Quisido III
    Michael M. Quisido IIIJul 9, 2019

    Nice One! Thanks for sharing.

  • Frederik Declercq
    Frederik DeclercqJul 9, 2019

    where are you from

  • Sheldon
    SheldonJul 10, 2019

    This is pretty cool. Can you help me understand the use case for this vs using Hugo and jeykll? Is this an alternative to creating your own static content and instead leveraging dev.to for hosting it all? Is there any advantage over rss feeds for integration for those of us who have our own site?

    • Maxime
      MaximeJul 11, 2019

      Hi, sure thing. It is instead to leverage dev.to to host it. As you're aware, a lot of people are publishing on dev.to. Maybe for the audience and visibility, maybe because they don't want to have to learn how to use Hugo and jekyll, or any other reason. But the point is, for those people I'm pretty sure it's hard to:

      • ask for a review before publishing
      • let someone somehow fix things in the article
      • keep track of changes if the article evolves
      • have a backup in case they mess up the article (failed save for e.g.)

      With this solution, they can be setup in 2mn to use git and continuous integration to deploy on dev.to 😊

      I hope it makes sense

  • Mandar Vaze
    Mandar VazeJul 12, 2019

    The option you suggested seems great but seems buggy. Only part of my blog post is "imported" (in the drafts)

  • Mandar Vaze
    Mandar VazeJul 13, 2019

    My blog also based on hugo.

  • Max Shash
    Max ShashAug 16, 2019

    Hi Maxime,

    Thank you for a great article. Strictly to the point without BS.

    I'd like to ask your opinion about the deployment automation service my team is working on.
    It is called DeployPlace.

    Deploy place is a service by developers for developers, with the possibility to easily deploy complex Java/Scala/Kotlin applications, as well as static websites or client-side projects directly from your CI.

    If you somehow have a chance, can you please take a look and let me know your opinion?
    DeployPlace.com

  • BoniW
    BoniWAug 23, 2019

    thats very awesome article,,
    blog.boniw.io

  • Mr F.
    Mr F.Nov 27, 2019

    This is a great article. thanks for sharing Maxime.

    I'm having trouble with my Travis CI build. It keeps failing when it gets to yarn:check

    any ideas?

    • Maxime
      MaximeNov 28, 2019

      Hi, thanks for the kind words.

      I've looked into your repo and apparently the latest commit is green on CI :). Is the issue gone?

      Otherwise, can you please make sure to:

      • upgrade all the dependencies and dev dependencies on your project
      • compare your travis conf with github.com/maxime1992/my-dev.to/bl... as I've had to fix a few things I may have forgotten to fix on the template

      Let me know how it goes

  • Josef Biehler
    Josef BiehlerJan 9, 2020

    Hey, I have one question regarding images that are used in posts. I have updated the image in section "2. Create a dev.to token". The PR already got merged. But the old image is still visible. I checked it in IE, too. As I never use IE, this browser can not have cached it.
    So someone else must cache the image. I already stumbled across this problem when updating a cover image a few times. I had to rename it in order to see the changed image.
    Do you know how this can be solved?

    • Maxime
      MaximeJan 12, 2020

      Hi Josef. Interesting. Can you please create an issue here github.com/maxime1992/dev-to-git ?

      I think I've got an idea how we could fix this.

      We could attach a param in the URL with the commit hash for ex that'd bust the cache :)

      • Josef Biehler
        Josef BiehlerJan 12, 2020

        [x] done

        Maybe I try a fix if I find some time

  • Maeling (she/her)
    Maeling (she/her)Jan 9, 2020

    Thanks for creating this template! I am trying to implement it but I'm a little unsure on how to actually push the updates I make in my repo to dev.to. I tried to copy the file structures and updated the dev-to-git.json file with the draft post id and relative path, but when I make changes to the blog post .md file, I don't see the changes being made when I visit the post draft link on dev.to. Am I going about this the wrong way?

    Do you mind providing a little more guidance on the steps after creating the blog post file?

    FYI: I just started using git this month, so I'm a noob when it comes to using GitHub

    Here's a link to my repo: github.com/maelingmurphy/my-dev.to

    Thanks!

  • Clive Da
    Clive DaJan 16, 2020

    can you HELP im getting prettier dev-to-git.json errors !

    full bug report here dev.to/osde8info/devto-autoposting...

    • Maxime
      MaximeJan 16, 2020

      Sure thing. I did reply on your post.

  • Keagan Van Rooyen
    Keagan Van RooyenJul 16, 2020

    I know this is an old post now, but I thought I would share in case anyone stumbles across this. I created a simple Python script to automate the creation of the blog post folder and markdown file. I plan on having the script get the ID of the post as well, but that is for the future. Check it out here.

  • Janne Kujanpää
    Janne KujanpääAug 13, 2020

    The main advantage of Github Actions over Travis is that you can get 2000mn of free time if the repo is private (which should be more than enough!).

    It should be noted here that private repository cannot host images for the article. User needs to use external image host or otherwise solve image upload to dev.to.

  • toonarmycaptain
    toonarmycaptainDec 4, 2020

    I'm having some issues with this. My github action was passing, but not posting, there were 422 errors in the log, then when I update the dependencies the action fails with log, 429 and 422 errors.

    Any ideas?
    github.com/toonarmycaptain/toonarm...
    TIA.

  • crisarji
    crisarjiDec 5, 2020

    Hey sir! awesome post, just started posting on my own and I am following this approach.

    Something that happened to me, and I want to share it here(I was looking among comments but did not find the same issue) was that the very first post worked like a charm in TravisCI!, but the second started to complain, I kept receiving this error message in TravisCI job log:

    0.92s$ if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then DEV_TO_GIT_TOKEN=$DEV_TO_GIT_TOKEN yarn run dev-to-git; fi
    yarn run v1.3.2
    (node:6600) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
    warning package.json: No license field
    $ dev-to-git
    [PUBLISHED] Article "Authentication with Vue(x)+Firebase" is already up to date
    [DRAFT] Article "Adding roles to the authentication with Vue(x)+Firebase" encountered an error:
    Error name: "HTTPError"
    Error message: "Response code 422 (Unprocessable Entity)"
    Error stack: "HTTPError: Response code 422 (Unprocessable Entity)
        at EventEmitter.emitter.on (..../blogs-dev.to/node_modules/dev-to-git/bin/dev-to-git.umd.js:7080:23)
        at processTicksAndRejections (internal/process/task_queues.js:86:5)"
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
    Done. Your build exited with 0.
    
    Enter fullscreen mode Exit fullscreen mode

    The PUBLISHED was a success every single time, the DRAFT kept showing that error(odd, with a 0 exited, so it was ok(?), or at least not affecting the status) till I manually set the published: true, then the next build the error was gone.

    Just wanted to share in case that this could be relevant for anyone else.

  • protium
    protiumMay 26, 2022

    Hey!
    It's been almost 3 years since my comment. I ended up building this github action: github.com/protiumx/blogpub/

    And here the article I wrote about it protiumx.dev/blog/posts/publish-yo...

    Also how I use it for my blog
    github.com/protiumx/blogp/

  • Rustam Apay
    Rustam ApayAug 11, 2022

    In the May I started to write a tutorial, I thought it will be 1 article, but it became 13 chapters :D
    I don't want to publish and update them manually on site and on github. Thats how I found this article.
    I didn't implement this idea yet, but I hope I can do that.

  • artydev
    artydevSep 9, 2024

    Great, thank you very much

  • Codefrombasics
    CodefrombasicsSep 18, 2024

    Great post! Git has truly revolutionized version control, making collaboration so much smoother. I particularly appreciate how Git branching allows for experimentation without risking the main codebase. For those looking to dive deeper, I've found that understanding Git's internal data structure—like how commits are stored as a chain—really helps in mastering more advanced features like rebasing. I've also written about some lesser-known Git tips that can streamline your workflow. Keep up the great work! GIT Training in Chennai

Add comment