This guest post was authored by Adam Armstrong. Adam has been using Titanium since 2010 and is an Appcelerator Titan. He is the Manager of Mobile Technology at AmWINS Group and does freelance work via https://implicitli.com. You can follow him on Twitter at @adamtarmstrong.
Prerequisites
- Alloy App
- CHANGELOG.md file
- changelog-parser npm package
- alloy.jmk file
What is a CHANGELOG?
A changelog is a file which contains a curated, chronologically ordered list of notable changes for each version of a project.
Note: A CHANGELOG is not the same as a git commit log. A CHANGELOG should only contain info the end user needs to know regarding changes to the software.
Convert CHANGELOG to Markdown
Titanium ships with a CHANGELOG.txt file. Change the file extension to .md so we can leverage all of the features of Markdown.
Convert your CHANGELOG contents from plain text to Markdown
To programatically access the contents, we need to adopt a standard. One of the most widely adopted standards is keep a changelog. Visit that link for more detail, but here is a rough outline of how a release entry might look.
## 4.2.9-2019-02-13
### Added
- Added that great feature you've been waiting for
### Fixed
- Fixed that annoying bug everyone hated
Add the ‘changelog-parser’ npm package (we will use this to export our CHANGELOG to a JSON Object at compile time)
- Simply run this to install the command-line version
npm install -g changelog-parser
- Open the file: **/app/alloy.jmk** (If it doesn’t exist, simply create one) and copy/paste this into that file
task("pre:load", function(event, logger) { const execSync = require('child_process').execSync; const fs = require('fs'); const path = require('path'); //ensure directory exists const dir = path.join(process.cwd(), 'app', 'lib'); if (!fs.existsSync(dir)) { logger.info(`Creating ${dir}`); fs.mkdirSync(dir); } //get ChangeLog and write to file const changelogObject = execSync("changelog-parser ./CHANGELOG.md").toString(); const myFile = dir + '/changelog.json'; fs.writeFileSync(myFile,changelogObject, 'utf8'); });
Now, when we compile our Alloy app, before anything else is compiled, the “pre:load” task runs, ensures the /app/lib directory exists, and then parses the `CHANGELOG.md` file into a JSON Object saved into a new file, `changelog.json`.
For reference, here’s how the above CHANGELOG release looks after being converted to a JSON Object:
{
"versions": [{
"version": "4.2.9",
"title": "4.2.9 - 2019-02-13",
"date": "2019-02-13",
"body": "### Added\n- Added that great feature you've been waiting for \n### Fixed\n- Fixed that annoying bug everyone hated",
"parsed": {
"_": [
"Added that great feature you've been waiting for",
"Fixed that annoying bug everyone hated"
],
"Added": [
"Added that great feature you've been waiting for"
],
"Fixed": [
"Fixed that annoying bug everyone hated"
]
}
}]
}
This gives you a Top Level Array `versions` with the first record [0] being the most recent version and each item in the Array includes:
- `body` is a flattened list of features in markdown format
- `parsed` is an array of features in plain text
- `Added` is an array of “Added” features
- `Fixed` is an array of “Fixed” features
Access your changelog.json file within your Mobile App
This is really straightforward. We simply get the file in the resourcesDirectory, read it, and then parse it as JSON.
var changelog = JSON.parse(Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory,'changelog.json').read());
Utilizing in your App
Where you go from here will greatly vary based on your app.
- Determine a new version has been installed
- On launch, you may want to get the current version installed using
Ti.App.version
- Then, compare against an already saved value of the last version that was installed using
Ti.App.Properties.getString('lastAppVersionUsed');
- If new version, then present a modal with the respective version array item in your changelog variable
Ti.API.info("New Version:\nVersion: " + changelog.versions[0].version + "\nReleased: " + changelog.versions[0].date);
Output:
New Version:
Version: 4.2.9
Released: 2019–02–13
- Whatever you do, don’t forget to update your saved value so that the user doesn’t get prompted again on the next launch.
Ti.App.Properties.setString('lastAppVersionUsed', Ti.App.version);
You now have a structured CHANGELOG in Markdown that is not only in a “friendly” format for git repos, but also available as a JSON Object within your app.
Follow us on social