Tools: Autopilot - the Final: From Localhost to the Cloud with GitHub Actions and CI/CD

Tools: Autopilot - the Final: From Localhost to the Cloud with GitHub Actions and CI/CD

Source: Dev.to

The Pipeline Architecture ## The Orchestrator (orchestrator.py) ## The Star Feature: "Director's Cut" ## Security and CI/CD: Sleeping Soundly ## The Final Result ## Autopilot Project Conclusion We have come a long way. We started by designing a Brain capable of reading (Post 2), we gave it personality with Creative Agents (Post 3), and we fought against bureaucracy to get some Hands (APIs) that could publish legally (Post 4). But there was one last big step left so as not to be a slave to my terminal. Right now, to publish, I had to be at my computer, open the console, and run python main.py. That's not "Autopilot." That's "Assisted Driving." Today, in the final chapter, we cut the cords. We move to the cloud and automate the entire process with my AI agents. The goal is GitOps: that my only interaction with the system is pushing changes to Git. Everything else must happen by magic (or rather, by GitHub Actions). I have designed a two-phase workflow: Detection and Preview Phase (Automatic): Publishing Phase (Manual): {{< mermaid >}} %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#f0f4f8', 'edgeLabelBackground':'#ffffff', 'tertiaryColor': '#e6e6e6'}}}%% graph TD %% Initial Node START([GitHub detects change in .md]) --> ORC I needed a script to join all the pieces together. To do this, I started developing a Python orchestrator that acts as a bridge between the Markdown file and my social media modules. This script is in charge of the "fine" logic that we sometimes forget: Sometimes, the AI doesn't get the tone exactly right, or I simply want to write the copy myself for a special announcement. To not lose automation but maintain control, I implemented a "Manual Overwrite" logic using Hugo's Frontmatter. If my script detects this in the article header: The system ignores the automatic generation and uses my exact words. It is the perfect balance: automation by default, manual control when necessary. The .github/workflows/autopilot.yml file is where the magic happens. Here we define the "Secrets" (my Twitter and LinkedIn API keys) and the rules of the game. The most interesting part is the environment protection: By defining the environment as production, GitHub forces me to review and approve the deployment. This prevents a code error or an AI "hallucination" from publishing unwanted content. Additionally, we have configured the system so that Twitter/X generates the Cards with images automatically and LinkedIn treats the content as an "Article," ensuring that on both networks the blog's featured image looks large and attractive. Now, my publishing process is this: In seconds, the content appears on Twitter and LinkedIn. Without opening the terminal. Without touching Python. From anywhere. Twitter/X Publication What started as an experiment to test how AI agents work and how they can help in my day-to-day life has turned into a professional publishing system. We have touched upon: This blog is no longer just a collection of texts; it is a living application that works for me. And now that I have free time... what shall we automate next? Thanks for joining me in this series. πŸ‘‰ Final Source Code: The entire project is available (and documented) on GitHub. Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse COMMAND_BLOCK: %% --- PHASE 1: AUTOMATIC --- subgraph Phase1 ["πŸ”Ή Phase 1: Detection and Preview (Automatic)"] direction TB ORC[Orchestrator Activates] %% Parallel Tasks ORC --> TASK1[Detect Language and Calculate URL] ORC --> TASK2[AI proposes Tweet and LinkedIn] %% Convergence TASK1 --> LOGS TASK2 --> LOGS LOGS[Show 'Preview' in Execution Logs] LOGS --> NOPUB[🚫 NOTHING PUBLISHED YET] end NOPUB --> PAUSE %% --- PHASE 2: MANUAL --- subgraph Phase2 ["πŸ”Έ Phase 2: Publishing (Manual)"] direction TB PAUSE((⏸️ AUTOMATIC PAUSE<br/>GitHub Environments)) PAUSE --> ALERT[πŸ”” Alert arrives to review deployment] ALERT --> DECISION{Approve Deployment?} %% Approval Path DECISION -- "Green Button (Approve) βœ…" --> EXEC[πŸš€ Execute real API call] %% Rejection Path (Implicit) DECISION -- "Reject / Cancel ❌" --> STOP([End of flow without publishing]) end %% Styles to highlight final steps style EXEC fill:#d4edda,stroke:#28a745,stroke-width:2px,color:#155724 style STOP fill:#f8d7da,stroke:#dc3545,stroke-width:2px,color:#721c24 style PAUSE fill:#fff3cd,stroke:#ffc107,stroke-width:3px Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: %% --- PHASE 1: AUTOMATIC --- subgraph Phase1 ["πŸ”Ή Phase 1: Detection and Preview (Automatic)"] direction TB ORC[Orchestrator Activates] %% Parallel Tasks ORC --> TASK1[Detect Language and Calculate URL] ORC --> TASK2[AI proposes Tweet and LinkedIn] %% Convergence TASK1 --> LOGS TASK2 --> LOGS LOGS[Show 'Preview' in Execution Logs] LOGS --> NOPUB[🚫 NOTHING PUBLISHED YET] end NOPUB --> PAUSE %% --- PHASE 2: MANUAL --- subgraph Phase2 ["πŸ”Έ Phase 2: Publishing (Manual)"] direction TB PAUSE((⏸️ AUTOMATIC PAUSE<br/>GitHub Environments)) PAUSE --> ALERT[πŸ”” Alert arrives to review deployment] ALERT --> DECISION{Approve Deployment?} %% Approval Path DECISION -- "Green Button (Approve) βœ…" --> EXEC[πŸš€ Execute real API call] %% Rejection Path (Implicit) DECISION -- "Reject / Cancel ❌" --> STOP([End of flow without publishing]) end %% Styles to highlight final steps style EXEC fill:#d4edda,stroke:#28a745,stroke-width:2px,color:#155724 style STOP fill:#f8d7da,stroke:#dc3545,stroke-width:2px,color:#721c24 style PAUSE fill:#fff3cd,stroke:#ffc107,stroke-width:3px COMMAND_BLOCK: %% --- PHASE 1: AUTOMATIC --- subgraph Phase1 ["πŸ”Ή Phase 1: Detection and Preview (Automatic)"] direction TB ORC[Orchestrator Activates] %% Parallel Tasks ORC --> TASK1[Detect Language and Calculate URL] ORC --> TASK2[AI proposes Tweet and LinkedIn] %% Convergence TASK1 --> LOGS TASK2 --> LOGS LOGS[Show 'Preview' in Execution Logs] LOGS --> NOPUB[🚫 NOTHING PUBLISHED YET] end NOPUB --> PAUSE %% --- PHASE 2: MANUAL --- subgraph Phase2 ["πŸ”Έ Phase 2: Publishing (Manual)"] direction TB PAUSE((⏸️ AUTOMATIC PAUSE<br/>GitHub Environments)) PAUSE --> ALERT[πŸ”” Alert arrives to review deployment] ALERT --> DECISION{Approve Deployment?} %% Approval Path DECISION -- "Green Button (Approve) βœ…" --> EXEC[πŸš€ Execute real API call] %% Rejection Path (Implicit) DECISION -- "Reject / Cancel ❌" --> STOP([End of flow without publishing]) end %% Styles to highlight final steps style EXEC fill:#d4edda,stroke:#28a745,stroke-width:2px,color:#155724 style STOP fill:#f8d7da,stroke:#dc3545,stroke-width:2px,color:#721c24 style PAUSE fill:#fff3cd,stroke:#ffc107,stroke-width:3px CODE_BLOCK: --- title: "My Great Post" social_text: "Today I don't want the AI to write for me. This post is so special that I hand-wrote this. πŸ‘‡" --- Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: --- title: "My Great Post" social_text: "Today I don't want the AI to write for me. This post is so special that I hand-wrote this. πŸ‘‡" --- CODE_BLOCK: --- title: "My Great Post" social_text: "Today I don't want the AI to write for me. This post is so special that I hand-wrote this. πŸ‘‡" --- COMMAND_BLOCK: jobs: publish: environment: production # <--- The key to security needs: check_changes steps: - run: python orchestrator.py Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: jobs: publish: environment: production # <--- The key to security needs: check_changes steps: - run: python orchestrator.py COMMAND_BLOCK: jobs: publish: environment: production # <--- The key to security needs: check_changes steps: - run: python orchestrator.py - Detection and Preview Phase (Automatic): GitHub detects a new .md file (or changes to an existing one). The Orchestrator activates. The system detects the post language (Spanish/English) and calculates the correct URL. The AI (or template system) proposes a tweet and a LinkedIn post. The system shows me a "Preview" in the execution logs, but does not publish anything. - GitHub detects a new .md file (or changes to an existing one). - The Orchestrator activates. - The system detects the post language (Spanish/English) and calculates the correct URL. - The AI (or template system) proposes a tweet and a LinkedIn post. - The system shows me a "Preview" in the execution logs, but does not publish anything. - Publishing Phase (Manual): The process pauses automatically thanks to GitHub Environments. I receive an alert to review the deployment. If I click the green button (Approve), the system executes the real call to the APIs. - The process pauses automatically thanks to GitHub Environments. - I receive an alert to review the deployment. - If I click the green button (Approve), the system executes the real call to the APIs. - GitHub detects a new .md file (or changes to an existing one). - The Orchestrator activates. - The system detects the post language (Spanish/English) and calculates the correct URL. - The AI (or template system) proposes a tweet and a LinkedIn post. - The system shows me a "Preview" in the execution logs, but does not publish anything. - The process pauses automatically thanks to GitHub Environments. - I receive an alert to review the deployment. - If I click the green button (Approve), the system executes the real call to the APIs. - Is it a post in English (/en/) or Spanish (/es/)? - Does it have a featured image to generate the Twitter/X or LinkedIn card? - Do I want the AI to write it, or do I want to write it myself? - I write my article in Markdown peacefully. - I run git push. - I have a coffee. β˜• - I check GitHub from my phone, see the "Preview" of the generated tweet (in the correct language). - I smile and hit Approve. - Prompt Engineering to define personalities. - Complex OAuth 2.0 APIs and token management. - Robust Python backend. - DevOps and CI/CD with GitHub Actions.