GitHub to LinkedIn, ship updates people actually read
Your product ships. Your GitHub shows the proof. But LinkedIn stays quiet because turning commits into a post is annoying, context-switch heavy, and always “later.”
This GitHub LinkedIn automation hits founders and indie hackers first, honestly. Developer advocates and marketing leads feel it too when “we should share this” turns into another unfinished draft.
This workflow watches your repo, writes a clean update people will actually read, generates a sharp code image, then publishes to LinkedIn. You’ll see what it does, why it works, and what you need to run it.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: GitHub to LinkedIn, ship updates people actually read
flowchart LR
subgraph sg0["Github Flow"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/github.dark.svg' width='40' height='40' /></div><br/>Github Trigger1"]
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/github.dark.svg' width='40' height='40' /></div><br/>GitHub File Download"]
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/linkedin.svg' width='40' height='40' /></div><br/>Post to LinkedIn"]
n3@{ icon: "mdi:robot", form: "rounded", label: "LinkedIn Content Creator", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Create Code HTML"]
n5["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>Generate Code Image"]
n6["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>GET the genarted Image"]
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/github.dark.svg' width='40' height='40' /></div><br/>Upload to Image Repo"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/merge.svg' width='40' height='40' /></div><br/>Merge"]
n9["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Extract Modified Files"]
n10@{ icon: "mdi:cog", form: "rounded", label: "Extract from File", pos: "b", h: 48 }
n11@{ icon: "mdi:robot", form: "rounded", label: "Structured Output Parser", pos: "b", h: 48 }
n12@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Fields", pos: "b", h: 48 }
n13@{ icon: "mdi:brain", form: "rounded", label: "OpenRouter Chat Model", pos: "b", h: 48 }
n14@{ icon: "mdi:cog", form: "rounded", label: "Extract from File1", pos: "b", h: 48 }
n8 --> n2
n12 --> n4
n0 --> n9
n4 --> n5
n10 --> n3
n14 --> n7
n5 --> n6
n1 --> n10
n1 --> n14
n7 --> n8
n13 -.-> n3
n9 --> n1
n6 --> n8
n3 --> n12
n11 -.-> n3
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n3,n11 ai
class n13 aiModel
class n5,n6 api
class n4,n9 code
classDef customIcon fill:none,stroke:none
class n0,n1,n2,n4,n5,n6,n7,n8,n9 customIcon
The Challenge: Turning commits into posts (without wasting your day)
Posting engineering progress sounds simple until you try to do it consistently. First you scan commits, then you open diffs, then you hunt for the one snippet that won’t confuse everyone. After that, you write, rewrite, simplify the wording, and still worry it reads like a changelog nobody asked for. Meanwhile, you lose your build focus, and the moment is gone. The worst part is that launches and improvements never compound in public because you keep shipping quietly.
It adds up fast. Here’s where it usually breaks down.
- You forget the details by the time you sit down to write, so the post turns vague and gets ignored.
- Pulling a code snippet that looks good in a feed takes longer than it should, especially if you’re reformatting or screenshotting.
- Manual posts drift in tone, which means your “voice” changes every week and people don’t know what to expect.
- One missed week turns into a month, because restarting the habit feels like extra work.
The Fix: Auto-generate LinkedIn posts from GitHub pushes
This workflow listens for new push events in your GitHub repository and pulls the files that changed. It extracts the relevant code text, then sends those changes to an LLM (via LangChain) to do two things at once: pick a snippet worth sharing and write a LinkedIn-ready explanation in plain English. Next, it builds a “Mac-window” style code preview in HTML with syntax highlighting and converts that HTML into an image through the HCTI API. Finally, it uploads the generated image back into GitHub (so you’ve got a stable hosted asset), merges the image with the LinkedIn copy, and publishes the post directly to LinkedIn under your profile.
The workflow starts with a GitHub push listener. Then the AI agent produces a short narrative and selects the snippet that best supports it. After the image render and upload, LinkedIn gets a complete post with text plus a clean visual, ready for a scroll-stopping feed.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you ship 4 meaningful updates a week. Manually, a typical “turn this into a LinkedIn post” routine takes about 20 minutes to understand the change, 20 minutes to write, and another 20 minutes to create a code screenshot that doesn’t look messy (about 1 hour per update). That’s roughly 4 hours a week. With this workflow, the push triggers everything, then you spend about 10 minutes reviewing and tweaking before it publishes. You get back about 3 hours weekly, and the posts actually happen.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- GitHub to detect pushes and host images.
- LinkedIn to publish posts automatically.
- OpenRouter API key (get it from your OpenRouter dashboard).
- HCTI.io API key (get it from your HCTI account settings).
Skill level: Intermediate. You’ll connect OAuth accounts and paste a couple API keys, plus update repo fields and your LinkedIn Person URN.
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
A GitHub push kicks things off. The workflow watches one repository for new push events, so every meaningful change can become a shareable update without you remembering to do it.
Changed files get identified and pulled. n8n figures out what actually changed, retrieves the file contents, and extracts the text so the AI isn’t guessing from a vague commit message.
AI writes the post and chooses the snippet. Through LangChain + OpenRouter, the workflow turns raw code changes into a LinkedIn post with context, plus a “best snippet” that supports the story.
The snippet becomes a clean image, then gets published. The workflow builds an HTML “Mac-window” code block, sends it to HCTI to render, stores the image in GitHub for hosting, merges image and copy, and posts to LinkedIn.
You can easily modify the prompt and posting rules to match your brand voice or add an approval step based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the GitHub Trigger
Set up the webhook listener so the workflow starts on repo pushes.
- Add and open GitHub Push Listener.
- Set Owner to
[YOUR_ID]and Repository to[YOUR_ID]. - Ensure Events includes
push. - Credential Required: Connect your githubApi credentials.
[YOUR_ID] in both Owner and Repository to match your repo settings.Step 2: Connect GitHub File Retrieval and Storage
Pull the changed file and prepare it for both text processing and binary handling.
- In Identify Changed Files, keep the default JavaScript to output
filePathfor each changed file. - Configure Retrieve Repo File with Resource set to
fileand Operation set toget. - Set File Path to
{{ $json.filePath }}in Retrieve Repo File. - Credential Required: Connect your githubApi credentials to Retrieve Repo File.
- Retrieve Repo File outputs to both Read Text Content and Binary to Property in parallel.
- Set Read Text Content Operation to
text. - Set Binary to Property Operation to
binaryToPropery. - In Store Image in Repo, set File Path to
{{ $('Retrieve Repo File').item.json.filePath }}and File Content to{{ $json.data }}. - Set Commit Message to
Upload generated image for {{ $('Retrieve Repo File').item.json.filePath }}in Store Image in Repo. - Credential Required: Connect your githubApi credentials to Store Image in Repo.
Step 3: Set Up AI Copy Generation and Parsing
Generate LinkedIn-ready content and extract structured fields for later steps.
- Open Compose LinkedIn Copy and keep Text set to
Data{{ $json.data }}. - Ensure Compose LinkedIn Copy has Prompt Type set to
defineand Has Output Parser enabled. - Verify OpenRouter Chat Engine is connected as the language model for Compose LinkedIn Copy and set Model to
google/gemini-2.5-flash. - Credential Required: Connect your openRouterApi credentials to OpenRouter Chat Engine.
- Ensure Structured JSON Parser is connected as the output parser for Compose LinkedIn Copy with the provided schema.
- In Map Content Fields, map the outputs with expressions like
{{ $json.output.post_title }},{{ $json.output.post_content }},{{ $json.output.code_snippet }},{{ $json.output.code_language }},{{ $json.output.hashtags }}, and{{ $json.output.character_count }}.
Step 4: Render Code Snippet Image
Convert the code snippet into a styled image using HTML-to-image rendering.
- In Build Code HTML, keep the JavaScript that builds
html,estimatedWidth, andestimatedHeight. - Configure Render Code Image with URL set to
https://hcti.io/v1/imageand Method set toPOST. - Set body parameters in Render Code Image: html to
{{ $json.html }}, google_fonts toFira Code, viewport_width to{{ Math.min($json.estimatedWidth || 800, 1920) }}, viewport_height to{{ Math.min($json.estimatedHeight || 400, 1080) }}, and device_scale to{{ 2 }}. - Set header Content-Type to
application/jsonin Render Code Image. - Credential Required: Connect your httpBasicAuth and httpHeaderAuth credentials to Render Code Image.
- In Fetch Rendered Image, set URL to
{{ $json.url }}and keep response format as file.
Step 5: Combine Media and Publish to LinkedIn
Merge the rendered image and text content, then publish to LinkedIn.
- Fetch Rendered Image outputs to Combine Image and Text for image data, while Store Image in Repo outputs to the same merge node.
- Ensure Combine Image and Text uses Mode
combineand Combine BycombineAll. - Configure Publish on LinkedIn Text to use the expression:
{{ $('Compose LinkedIn Copy').item.json.output.post_title }}+{{ $('Compose LinkedIn Copy').item.json.output.post_content }}+{{ $('Compose LinkedIn Copy').item.json.output.hashtags }}+Link to Github: {{ $json.content._links.html }}. - Set Person to
[YOUR_ID]and Share Media Category toIMAGEin Publish on LinkedIn. - Credential Required: Connect your linkedInOAuth2Api credentials to Publish on LinkedIn.
Step 6: Test and Activate Your Workflow
Validate each stage and switch the workflow to active mode.
- Click Execute Workflow and push a test commit to the repo configured in GitHub Push Listener.
- Confirm Identify Changed Files outputs one or more
filePathitems. - Verify the AI output fields in Map Content Fields and that Render Code Image returns a valid image URL.
- Check that Publish on LinkedIn creates a post with the generated text and attached image.
- When satisfied, toggle the workflow to Active for production use.
Watch Out For
- GitHub credentials can expire or need specific permissions. If things break, check your n8n credential test and the repo access token scopes first.
- If you’re using external rendering (HCTI), processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Common Questions
About 30 minutes if your accounts and API keys are ready.
Yes, but you’ll want someone comfortable with OAuth and API keys. No coding is required, though minor field edits (repo name, LinkedIn URN) are part of setup.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in OpenRouter model usage and HCTI image rendering costs.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
You can tweak the “Compose LinkedIn Copy” agent prompt to match your tone, audience, and post length. If you prefer OpenAI or Anthropic, swap the “OpenRouter Chat Engine” node for your model node and keep the same structured output. Many teams also customize “Identify Changed Files” to ignore docs or dependency bumps, then adjust “Build Code HTML” to match their preferred theme and font.
Usually it’s token scope or an expired OAuth connection. Reconnect GitHub in n8n, confirm the workflow has access to the source repo and the target repo used by “Store Image in Repo,” then re-run a test push. If failures happen only on larger commits, the file retrieval step may be hitting size limits, so narrowing the snippet selection helps.
If you self-host, there’s no execution cap (it mostly depends on your server and API rate limits). On n8n Cloud, capacity depends on your plan, and this workflow runs once per push event, so most small teams are fine unless they push constantly.
For this specific job, usually yes. You’re mixing GitHub file handling, an AI agent, structured parsing, HTML generation, an external render call, and a multi-step merge before posting. n8n handles that kind of branching and data shaping without turning your automation into a pile of paid “tasks.” Also, self-hosting matters here because a busy repo can create lots of executions. Zapier or Make can still be fine for simple “new commit → post message” flows, just don’t expect the same control over snippet selection and image rendering. If you want help deciding, Talk to an automation expert.
Ship your work, then let the workflow translate it into a post people can understand. The repetitive part is handled, so you can stay in build mode.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.