Access your CHANGELOG within Axway Appcelerator to implement a “What’s New” Feature
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
Appcelerator 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 doesnt exists, 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 markdwoon 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 straight forward. 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, dont forget to update your saved value so that the user doesnt get prompted again on the next launch
Ti.App.Properties.setString('lastAppVersionUsed', Ti.App.version);