Automated release notes - eliminating manual process from delivering product updates
Ask any technical writer and they will tell you that writing release notes is one of the biggest struggles in their work life. Every company takes a different approach: from bullet-style one-sentence updates, to entire booklets of all product changes that happened between two major releases. Personally, I never enjoyed writing them, as the business side of the team always wants to emphasize the "cutting-edgeness" of the new functionality, which quickly turns into marketing copy.
In my current role, release notes are owned by the product owners, not the documentation team. We use MadCap Flare for writing all our content, a software whose annual subscription fee causes a headache for all managers who have to approve its purchase order, so not everyone has access to it. Before my update, the POs wrote their updates in a Word file and we imported it to Flare through its built-in import function. However, in a biweekly release cycle this proved to be too error-prone, as POs had to use SVN, which caused many conflicts within the file and numerous broken builds on Jenkins.
Like many organizations in the IT industry, mine wasn't immune to the AI wave. I started using GitHub Copilot daily and it became my go-to tool for many tasks. I got the idea to make the release notes process easier for everyone, so I employed Copilot in VS Code to help me implement the following idea:
A script that downloads the release notes text from a Confluence page, converts it into a snippet, applies the necessary syntax and formatting, and adds it to the release notes topic in Flare — thus eliminating the technical writer from this process (mostly).
Approach
To give more context: for each biweekly SaaS release, we publish release notes for 6 different products. Before automation, the workflow looked like this:
BEFORE
──────────────────────────────────────────────────────────────────
PO writes in Word → Commits to SVN → TW imports to Flare
│ │
▼ ▼
SVN conflicts Broken Jenkins builds
To fix this, I created 6 parent pages in Confluence, one per product, and a set of formatting rules for Product Owners to prevent errors in the pipeline:
- Use h4 headings for Enhancements, Known issues, and Addressed issues
- Use bold for UI labels
- Use the provided template when there are no updates
The Confluence part
The setup requires two things from each Confluence page:
- A tag — the script uses it to create a matching folder within the Flare project and to give the snippet a descriptive name.
- The PageID — found in the URL when you open Page Information. The script uses it to fetch the page content via the Confluence API.
You also need to create a Personal Access Token (PAT) for Confluence so that the script can authenticate API requests.
Under the hood
The initial version of the Python script was written with significant help from an AI agent. In my case Claude Sonnet 4.5. My role was to define the requirements, provide scaffolding and instructions, review the output, and make adjustments to the script and configuration file. This kind of human-AI collaboration is exactly what makes AI useful for technical writers: you bring the domain knowledge, the AI handles the implementation details.
The libraries used are all standard Python libraries, with the exception of requests (for the Confluence API call) and python-dotenv (for loading your .env file containing the Personal Access Token).
At a high level, the script does the following:
AFTER (automated workflow)
──────────────────────────────────────────────────────────────────
PO writes on Python script MadCap Flare
Confluence (automated) project
┌─────────────┐ ┌──────────────────┐ ┌────────────────┐
│ Release notes│ │ Fetch via API │ │ │
│ per product │────▶│ Parse HTML │────▶│ Release notes │
│ (6 pages) │ │ Convert styles │ │ topic updated │
│ │ │ Apply Flare │ │ │
│ │ │ syntax │ │ Ready for │
│ │ │ Insert release │ │ deployment │
│ │ │ variable │ │ │
└─────────────┘ └──────────────────┘ └────────────────┘
The result
The end product was well received. The amount of work for product owners was reduced to writing or pasting text into a Confluence page. And that's it. No SVN, no Word imports, no broken builds. Once I receive confirmation that all release notes are drafted on Confluence, I execute the script and everything is ready for deployment in less than 10 minutes.
Further improvements
After the initial script was implemented, the technical writer still had to manually prepare Flare projects before every release. Two repetitive tasks remained:
- Updating the release version variable — The global variable for the release version had to be updated in each product's Flare project individually. To fix this, I created a PowerShell script that imports the variable from the Global Flare project to each product project in one go.
- Moving previous release notes — The content under the Latest Release heading had to be moved to the Previous Releases section. A second Python script now handles this automatically, moving the snippet file from one section to another.
With these additions, the technical writer only needs to update the version variable in the Global project. Everything else is automated.
FINAL WORKFLOW (end-to-end)
──────────────────────────────────────────────────────────────────
TW updates version POs confirm TW runs
in Global project drafts are ready the script
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌───────────────────┐ ┌─────────────────┐
│ PowerShell │ │ Python script │ │ Python script │
│ imports var │ │ fetches, converts │ │ moves previous │
│ to all │ │ and inserts │ │ release to │
│ products │ │ release notes │ │ archive section │
└──────┬───────┘ └────────┬──────────┘ └────────┬────────┘
│ │ │
└─────────────────────┼────────────────────────┘
▼
Ready for deployment
(< 10 minutes)
In conclusion
This kind of approach to AI is what makes it a genuinely useful tool for technical writers. You could've done all this without it, but it would take considerably more time, unless you have serious Python and scripting knowledge. Without that, you would need to bother your favourite developer colleague and hope they aren't buried with their own tasks. GitHub Copilot makes all the difference, by providing you your own personal developer who is never condescending or annoyed by your questions.