Shorten the Travis build time of Meilix

Meilix is a lubuntu based script. It uses Travis to compile and deploy the iso as Github Release. Normally Travis took around 17-21 minutes to build the script and then to deploy the iso on the page. It is quite good that one gets the iso in such a small interval of time but if we would able to decrease this time even more then that will be better.

Meilix script consists of basically 2 tests and 1 deploy:

The idea behind reducing the time of Meilix building is to parallely run the tests which are independent to each other. So here we run the and parallely to reduce the time upto some extent.
This pictures denotes that both the tests are running parallely and Github Releases is waiting for them to get complete successfully to deploy the iso.

Let’s see the code through which this made possible:

    - script: ./
    - script: 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./scripts/; fi'
    - stage: GitHub Release
      script: echo "Deploying to GitHub releases ..."

Here we included a job section in which we wrote the test which Travis has to carry out parallely. This will run both the script at the same time and can help to reduce the time.
After both the script run successfully then Github Release the iso.

Here we can see that we are only able to save around 30-40 seconds and that much matters a lot in case if we have more than 1 build going on the same time.

Links to follow:
Travis guide to build stages

Firefox Customization for Meilix

Meilix a lightweight operating system can be easily customized. This article talks about the way one must proceed to customize the configuration of Firefox of Meilix or on its own Linux distro and how to copy the configuration file of Firefox directly to the home folder of the user.
Meilix script contains a pref.js file which is responsible for providing the configuration. This file contains various function through which one can edit them according to its need to get the required configuration of its need.

Let’s see an example:

user_pref("browser.startup.homepage", "");

This line is used to set the browser startup page and it can be edited according to user choice to find the same page whenever he starts his Firefox.

There are several lines too which can be edited to make the required changes.

How does this work?

This is the Mozilla User Preference file and should be placed in the location /home/user_name/.mozilla/firefox/*.default/prefs.js. It actually controls the attributes of Firefox preference and set the command from here to change it.

How to use it?

One can directly go and edit it according to the choice to use it.

How meilix script uses it to change the user preference?

As we can see that .mozilla folder should be under the home directory, therefore we copy the .mozilla to the the skel folder, so that it gets automatically copied to the home location and we would be able to use.
There is also a shell script which comes in handy to implement the browser startup page and the script even copies the configuration file.


2.# firefox
4.for user_name in `ls /home/`
  6.preferences_file="`echo /home/$user_name/.mozilla/firefox/*.default/prefs.js`"
  7.if [ -f "$preferences_file" ]
    9.echo "user_pref(\"browser.startup.homepage\", \"\");" >> $preferences_file

This file is taken from here. And it used in Meilix to run the script to set the default startup page in Firefox. This will be taken input from the user end from the Meilix Generator webapp and it will change the line 9 url according to the input given by the user.
On line 3, *.default will set automatically by the script itself, it generated randomly.
After that, the script will copy the prefs.js in its location and it will implement the changes.

Links to follow:

Firefox-preference guide

Generate Requirement File for Python App for Meilix-Generator

Meilix-Generator is based upon Flask (a Python framework) which has several dependencies to fulfill before actually running the app properly. This article will guide you through the way I used it to automatically generate the requirement file for Meilix Generator app so that one doesn’t have to manually type all the requirements.

An app powered by Python always has several dependencies to fulfill to run the app successfully. The app root directory contains a file named as requirements.txt which contains the name of the dependency and their version. There are features ways to generate the requirement file for an app but the one which I will demonstrate is the best one. So I used this idea to generate the requirement file for webapp Meilix Generator.

Ways to get the requirement.txt

The internet has a featured way through which one has just to run a command to get a list of all the different dependencies within an app.

pip freeze > requirements.txt

This way will generate a bunch of dependencies that we not even required.

Why do we really require to generate a requirement file?

Yes, one may even ask that we can even write the dependency in the requirements.txt file. Why do we need a command to generate it?

Since because it will take care of two important things:
1. It will ensure that all the dependencies have been included, from user input one may forget to find some of the dependency and to include that.

  1. It will also take care of the Python Package Version Pinning which is really important. People use to version pinning for Python requirements as “>=” style. It’s important to follow “==” style because If we want to install the program in one year in the future, the required packages should be pinned to assure that the API changes in the installed packages do not break the program. Please read here for more info.

The way mentioned below will ensure to provide both these features.

How I generated it for Meilix Generator?

Meilix Generator run on Flask that require a requirement.txt file to fulfill the dependencies. Let’s get straight to the way to generate it for the project.

First we will simply create a file in which we will simply mention all the dependencies in a simple way:


Now we will use a command to latest packages:

pip install --upgrade -r

#Note that if you would like to change the requirements, please edit the file and run this command to update the dependencies

Then type this command to generate the requirements.txt file from

pip-compile --output-file requirements.txt

#fix the versions that definitely work for an eternity.
This will generate a file something as:

click==6.7                # via flask
itsdangerous==0.24        # via flask
Jinja2==2.9.6             # via flask
MarkupSafe==1.0           # via jinja2
Werkzeug==0.12.2          # via flask

Now you generated a perfect requirements.txt file with all the dependencies satisfied with proper python package pinning.

The meilix-generator repo which uses this:

Heroku Deployment through Travis for Meilix-Generator

This article will tell the way to deploy the Meilix Generator on Heroku with the help of Travis. A successful deployment will help as a test for a good PR. Later in the article, we’ll see the one-button deployment on Heroku.

We will here deploy Meilix Generator on Heroku. The way to deploy the project on Heroku is that one should connect its Github account and deploy it on Heroku. The problem arises when one wants to deploy the project on each and every commit. This will help to test that the commits are passing or not. Here we will see that how to use Travis to deploy on Heroku on each and every commit. If the Travis test passed which means that the changes made in the commit are implemented.
We used the same idea to test the commits for Meilix Generator.

Idea behind it

Travis (.travis.yml) will be helpful to us to achieve this. We will use this deploy build to Heroku on each commit. If it gets successfully deployed then it proves that the commit made is working.

How to implement it

I will use Meilix Generator repository to tell the way to implement this. It is as simple as editing the .travis.yml file. We just have to add few lines to .travis.yml and hence it will get deployed.

  provider: heroku
    secure: "YOUR ENCRYPTED API KEY"     # explained below
  app: meilix-generator                    # write the name of the app
    repo: fossasia/meilix-generator                # repo name
    branch: master                        # branch name

Way to generate the api key:
This is really a matter of concern since if this gets wrong then the deployment will not occur.


  • cd into the repository which you want to deploy on Heroku.
  • Login Heroku CI and Travis CI into your terminal and type the following.

travis encrypt $(heroku auth:token) --add deploy.api_key

This will automatically provide the key inside the .travis.yml file.

You can also configure manually using

travis heroku setup

That it, you are done, test the build.

Things are still left:

But we are still left with the test of the PR.
For this we have to create a new app.json file as:

    "name": "Meilix-Generator",
    "description": "A webapp which generates iso for you",
    "repository": "",
    "logo": "",
    "keywords": [
    "env": {
        "APP_SECRET_TOKEN": {
            "generator": "secret"
        "ON_HEROKU": "true",
        "FORCE_SSL": "true",
        "INVITATION_CODE": {
            "generator": "secret"
    "buildpacks": {
            "url": "heroku/python"        # this is the only place of concern

This code should be put in a file in the root of the repo with the name as app.json.
In the buildpacks : the url should be the one which contains the code base language used.

This can be helpful in 2 ways:

  1. Test the commit made and deploy it on Heroku
    2. One-click deployment button which will deploy the app on Heroku
  • Test the deployment through the URL:

  • Way to add the button:


How can this idea be helpful to a developer

A developer can use this to deploy its app on Heroku and test the commit automatically and view the quality and status of PR too.

Useful repositories and link which uses this:

I have used the same idea in my project. Do have a look:
deployment on Heroku
one-click deployment
app.json file schema   

Setting Environment Variables up in Travis and Heroku for Meilix and Meilix-Generator

Meilix Generator is a webapp whose task is to take input as a configuration and start the Meilix build. But an anonymous person cannot start the Meilix build of any user and deploy the release in the repository. There are ways which are used as authentication passes through environment variable to start the build. In this article, I show the way I used to trigger Meilix by setting up environment variables in Meilix Generator.

Environment variables are of great use when one has to supply personal token in an open-source project for accessing the repository. So down there, we will have ways to configure the variables in Heroku and Travis. There are so many wikis out there but this one is the blend of both Heroku and Travis.


There are several ways to setup variables in Heroku. The way I’m going to describe below is used to access Travis build using Heroku.
Using the Heroku variable generated using Travis will help to trigger the build on Travis.


We will use Travis CLI to generate a token (unique and keep it secret). Then provide the token as a variable name to the Heroku.
This Travis token will give access to the Heroku to trigger the build on that particular Travis account. We use variable to provide the token since in the script we will use this variable as an environment variable to fetch the token in the place of token like as $token.
Open your terminal and type the following:

sudo apt install ruby ruby-dev
sudo gem install travis                       	# install Travis CLI
travis login --org   					# login into Travis
travis token --org		# generate your secret personal access token

You will get a token, copy and paste it into your Heroku app’s settings config vars token. You have to use the `KEY` as the variable which is used in the script for triggering the build. Save it and you are done the setting of the token in the Heroku.


Now it’s time for Travis token.
It is used to deploy the build to that repository only.
We can use the token in two ways either paste it in the setting of that repository on Travis or pasting the encrypted form of that in the .travis.yml file in that repository. Both will work. But one thing to remember that you must have the write access to that repository.


It is used in .travis.yml file as an environment variable to successfully build and deploy the application as a Github release.
The token gives the permission to Travis to deploy the build application in the GitHub release of the repo(if one using to deploy it there only).
Head up to Github and generate a personal access token with scope repo. Copy the generated token in a safe place.

Way 1:

Paste the token in the setting of the repo in Travis in Environment Variable option. Now it will access the Github repository since it has got the permission from the personal token generated from Github.

Way 2:
Open terminal:

cd repo_name				# cd into the cloned repo
travis encrypt secret_token	#replace secret_token with the token generated


travis encrypt secret_token -r user/repo 	#if you are not in the repo

Copy that encrypted token and paste it in proper format in the .travis.yml file. Now you enabled Travis giving permission to release the build.

How can this idea be helpful to a developer

A developer can use this to build the Github Release in its repository. One can secure its token using this technique. One can use it to trigger its personal project in Travis using Heroku.

Useful repositories and link which uses this:

I have used the same idea in my project. Do have a look
about environment variable
encryption keys
triggering build

Building Meilix in Travis using Heroku

Suppose you have to trigger (start) Travis but not through making a commit but through clicking a button on the webapp of the Meilix Generator. Through the webapp of Meilix Generator, we can pass the tag of the build which will be initiated and can also get the build link which is built by Travis.
Heroku is the place where we have deployed our webapp and through a button on the webapp that we used to start the build on the Travis. We have the access to give a tag to the build and with the help of this, we can even predict the URL of the build beforehand. So one can use it for its own personal project in a number of ways. And how I used this feature in Meilix Generator using Meilix script is described below:

How I used this idea

FOSSASIA meilix repository consists the script of a Linux Operating System based on Lubuntu. It uses Travis to build that script to result in a release of an iso file.

Now we thought an idea of building an autonomous system to start this build and get the release and in the meanwhile also make some required changes to the script to get it into the OS. We came up with an idea of a webapp which ask user its email id and tag of the build and till now a picture from the user which will be set as a wallpaper. It means the user would be able to config its distro according to its need through the graphical interface without a single line to code from the user end.

Through the webapp, a build button is taken as an input to go to a build page which triggers the Travis with the same user configuration to build the iso and deploy it on Github page. The user gets the link to the build on the next page only.

How I implemented this idea

Thanks to Travis API without which our idea is impossible to implement. We used a shell script to outframe our idea. The script takes the input of the user’s, repository, and branch to decide to where the trigger to take place.

There are two files one as travis_token as:

fossasia meilix master    # in the format of user repo branch

And as:  

cat travis_tokens | while read line;     # this lines takes input of the user, repo and branch
    for ((i=2; i<len; i++)); do
        branch="${array[i]}"            # supplied each value as variable
                    \"email\":\"${email}\",    # supplied email and travis tag as environment variable
    echo "This Link Will be ready in approx 20 minutes"
    echo "${TRAVIS_TAG}/meilix-zesty-`date +%Y%m%d`-i386.iso"                  # a pre-predication of the link, we provide tag from user and date from system.
        curl -s -X POST \           # sending an API POST request to Travis to trigger the build of most recent commit 
            -H "Content-Type: application/json" \
            -H "Accept: application/json" \
            -H "Travis-API-Version: 3" \
            -H "Authorization: token ${KEY}" \     # this is stored in Heroku as KEY as environment variable and supplied from there only
            -d "${body}" \
            "${user}%2F${project}/requests"  #%2 is used to interpret user and repo name as a single URL segment.

After the trigger, you will get email which consists of a downloadable link to the iso.

How can this idea be helpful to a developer

There are lots of ways a developer can use this idea out. If a developer wants their user to automatically trigger the build and get the release build directly.

One can use it to set even the commit message through the shell script and customizing build configuration like replace, merge or deep_merge a configuration with the original .travis.yml file present in source repo.

Useful repositories and link which uses this:

Know more about Travis API v3:
Triggering the build
API blog

Have a look at our webapp and generate your own iso:

Source code here:

Building the Meilix Generator with Flask

Meilix Generator is a webapp which is used to trigger the Travis build of Meilix and mail the user the link of the iso. Meilix Generator webapp is based on Flask. This blog shows that how easy is to build a webapp and take the HTML files to render it into the webapp as well as to call and pass various function. Here I used Flask, the Python framework to render the HTML templates and send requests for various purposes (mentioned later in the article) without coding everything from scratch because of import facility of the Flask.

What is Flask?

Flask is a Python micro web framework based on Werkzeug, Jinja 2 template engine. It is used as the backbone of the webapp. It features us with a whole set of Python from which we can easily generate webapp. It is micro as it has no tools and no library itself. It come up with minimum requirements and one who needs can import different library and use it. And I used several import function for Meilix Generator like render_template, send_from_directory, etc.

Implementation (The use case in Meilix Generator)

First of all, the installation process: We will do the installation in a virtual environment. We prefer virtual environment to differentiate the Python working environment since few programs are there which require different Python versions to work.
Install virtual environment 

sudo pip install virtualenv

Now go to the folder (project) and activate it using

. venv/bin/activate

Now install Flask

pip install flask
Creating your project

Now it’s time to create a simple project in the directory.
Let’s use HTML as the frontend. In the folder create styles.css for styling and index.html template for the frontend of the page.We will make one file which would look similar to this: 

from flask import Flask, render_template
app = Flask(__name__)
def index():
	"""Index page"""
	return render_template("index.html")
if __name__ == '__main__':

Flask looks for the / (root) path and here the root return the main template (index.html) which is the main function.

Compiling it to view the page:

export FLASK_DEBUG=1
flask run

You will find your page at

More options (how more it can help you)

  • Add more HTML template options and refer it in
  • Easily use Github API  from a different .py file (this file should get import to to fetch data like: : It will fetch user name, repos, followers and many more important information.

How I used this idea for FOSSASIA (Meilix Generator)

I used Flask for the backbone of project Meilix Generator. First, I used from function to import various library needed for the project and then made several functions for the same. Let’s understand the concept using few example:

from flask import Flask, render_template
def about():
		#About page
		return render_template("about.html")


from flask import Flask, send_from_directory
def uploaded_file(filename):
		return send_from_directory(app.config['UPLOAD_FOLDER'],filename)

For more details file can be found here of the Meilix Generator repository where we used the above idea.

Important Links and Repositories:

Customizing Chromium for the Meilix Generator

Imagine if you are able to vanish that star icon of the bookmark which is on the extreme right of address bar. Disable auto-fill option, disable some particular extension to get install and many more things. And you could even distribute it to any friend to get the same setting within just copy and paste. We are working on such features for the FOSSASIA Meilix generator for Chromium.

Chromium is one of the most popular browsers. But had you ever thought how grateful it would be if you are able to customize your chromium to a larger extent? Sometimes it feels that few features are there which we merely used.

So here it is the way to tailor cut the specification of the browser and you can even give it to your friend to try out the feature. It just needs to copy and paste a file for your friend. Not forget to mention from where do I get this file: fossasia/meilix

How can you do that?

This gist is a .json file which has to be copied in the etc/chromium-browser/policies/managed with the name chrome.json. That’s it.

It’s a policy template of Linux for the browser Chromium. This file contains different policies and they are commented. Uncomment the required values and set your desired values.

Format of the policy of the JSON file.

Each policy is well-structured so that a person can easily understand and change its values.

Let’s take an example:

1 // Enable Bookmark Bar
2 //-------------------------------------------------------------------------
3 // Enables the bookmark bar on Google Chrome.  If you enable this setting,
4 // Google Chrome will show a bookmark bar.  If you disable this setting, users
5 // will never see the bookmark bar.  If you enable or disable this setting,
6 // users cannot change or override it in Google Chrome.  If this setting is
7 // left not set the user can decide to use this function or not.
8 //"BookmarkBarEnabled": true,

This is an example of controlling of bookmark bar which is mention on line 1
Line 2 is left intentionally for proper formatting
Line 3-7 explains the purpose of the policy, it explains itself quite briefly
Line 8 is the by default set option, to alter it, uncomment it and reverse the values.

This same way is being followed throughout. There are many other options which act as a boon.

Edit the file and share it with your friends and ask them to copy it in the same location and then they can also get the benefit of the feature.

Building Metapackages to Customize the Meilix Linux Distro Generator

This article will guide you to build a metapackage with your required configuration and to use it inside the meilix distro to customize and use the inbuild metapackages to customize the configuration file of packages and properties of various browsers.
Metapackages are scripts which contain the link to existing packages. It’s a .deb file. As packages include dependencies analogically metapackages include packages. So, we can say that metapackages do not contain actual software, they depend upon packages. This guide will help you to make your own metapackage easily, configure it and distribute it among your friends and other Linux users.

How to get started to build a metapackage for meilix?

At first one needs to sort out the metapackages that it needs to be there in the metapackages. One can also come up with the package which he don’t want to install but that comes under dependency of the some package.
It’s easy, a few lines of commands and you will have a .deb metapackage in your hand.
We will use equivs as a tool to build metapackages.

Install equivs :

sudo apt-get install equivs
equivs-control ns-control

This will create a file with the name ns-control and that files looks similar to this:

1.### Commented entries have reasonable defaults.
2.### Uncomment to edit them.
3.# Source: <source package name; defaults to package name>
4.Section: misc
5.Priority: optional
6.# Homepage: <enter URL here; no default>
7.Standards-Version: 3.9.2
8.Package: <package name; defaults to equivs-dummy>
9.# Version: <enter version here; defaults to 1.0>
10.# Maintainer: Your Name <[email protected]>
11.# Pre-Depends: <comma-separated list of packages>
12.# Depends: <comma-separated list of packages>
13.# Recommends: <comma-separated list of packages>
14.# Suggests: <comma-separated list of packages>
15.# Provides: <comma-separated list of packages>
16.# Replaces: <comma-separated list of packages>
17.# Architecture: all
18.# Multi-Arch: <one of: foreign|same|allowed>
19.# Copyright: <copyright file; defaults to GPL2>
20.# Changelog: <changelog file; defaults to a generic changelog>
21.# Readme: <README.Debian file; defaults to a generic one>
22.# Extra-Files: <comma-separated list of additional files for the doc directory>
23.# Files: <pair of space-separated paths; First is file to include, second is destination>
24.# <more pairs, if there's more than one file to include. Notice the starting space>
25.Description: <short description; defaults to some wise words>
long description and info

second paragraph


Now the question is what to do with this:
Line 3-7 : the control information of the source packages.
Line 8-25 : the control information for the binary packages
Source packages are those packages which contain the source code of the package. One can compile the source and install it in any architecture of the machine .
Binary packages are those packages which are specific to the architecture of machine. And one can easily install it with a click.

Description of important lines:
Line 3: The name of the source package, same to Line 8
Line 4: section of the distribution
There are various categories in which a source package can be put into.
Line 9: version of the package, it is helpful if you want it install packages of a particular version
Line 11: you have to write the dependencies of the packages #better remain this commented
Line 12 : Include the name of the packages that you want to include in the metapackage
Line 17: Architecture is set to all that is for both 32 and 64 bit.
Line 25: Provide description

Next is what
Then after filling up the text file, now it’s time to build it.

Build the package:

equivs-build ns-control

Now it will run and will give you a .deb file.
dpkg i *.deb will install the deb file.

This is the metapackage which contains the packages which you have included.
I have used this wiki as a source for the required information.

Suppose one of most popular metapackage : gnome-desktop-environment – It is the a desktop environment gnome flavoured. It gives the graphical user interface to the user with popular email, office tools, music and other wide range of applications.

How a common Linux user can get the benefit of it?

We know that most of the people avoid Linux because of its beautiful command line feature. They just want to use mouse/touchpad throughout.
With the help of this, a person can build a metapackage. This one can distribute to its friend and can also use for the future purpose.
One can also use this to make a collection of metapackages of different packages like hacking tools, text tools, etc.

How we uses the metapackages?

Meilix script uses the metapackages for building of all the required packages. In our webapp version (meilix-generator) we made several metapackages that will be asked from the user and a user can choose one among them according to its requirement. It will also contain the information that which packages the metapackage is made of.

Suppose event metapackages include the packages needed by the people for the events purpose which will predefined by us and they will consist of lightweight text editor, media player, document viewer etc. In an education related metapackage one contain packages related to school, workshop.

Now meilix repo contains its own metapackages that it uses to contain the distro.

How meilix metapackage is used to control distro configuration?

We can even control the distro properties including the browser configuration, it’s startup page, search page and many more things through metapackages. Let’s see how:

We created a metapackage with the name meilix-default-settings and used it to config various features in the distro. The meilix settings metapackage consists of etc folder where we can made the changes to get it on the distro. We can even include property folder in the .config under skel folder to copy the changes into the home folder of the new user. To change the chrome configuration, we need to edit the chrome.json file. To change firefox configuration we need to edit prefs.js file.

The metapackage folder is:

Repository using metapackages  (the webapp)

Meilix System Lock

Meilix-Systemlock has to two main shell files: and The purpose of the script is that if the is called, the content inside the home directory will be reset after rebooting of the system. And it will be in that state of getting back reset to home directory until is being called.

An Example to illustrate

Suppose in a computer lab, the students are given computers and they make changes which don’t seem convenient to the maintainer of the lab. The maintainer freezes the system to have a clean state, and the students use the computer and make it “dirty”, and the reboot restores to the clean state when maintainer running freeze. As soon as the is being called system will copy the files in the home directory to another place, then reboot. Reboot and copying don’t occur parallelly.

The system remains in the frozen state and every time when its get rebooted, it gets to the same state of home directory when it is being frozen. This can be stopped by calling This can be helpful for the maintainer for creating a new freeze point.
I get the idea through chat with Yeo Wei and used the logo from here.

Diagram for clear representation

How does it solve someone’s problem in daily life?

As I explained in the example, it can easily solve the problem of a computer lab assistant at a school, college, public cafe, etc. I request this idea should reach to them, and they can run the to freeze the system so as to avoid the dirtiness made by a third person. Maintainer generally left out this dirt for next user who is going to work on the same PC. But this technique will make the PC new and new user doesn’t have to clean the dirt made by the previous user and they can setup their environment freshly.

Understanding the Important Code Mechanism:

In the script

Line: 44

echo “sudo rsync -a –delete /etc/.ofris/$ofris_user/ /home/$ofris_user/” >> ofris_tmp

– this line restore the files stored in /etc/.ofris/user to /home/user” into /etc/rc.local (which runs every time computer boots).

Line: 38, 39

if [ $ofris_rst = 1 ]; then 
echo "Error: The system has been locked, please select the fourth choice to unfreeze the system..."

– this line stops the execution of if it hasn’t been unlocked yet.

In the script

Line: 1

grep -v "sudo rsync -a --delete /etc/" /etc/rc.local > ofris_tmp_b

– this check if the rc.local is being modified or not.
And rest command removes the created folder and restore the home folder to its original state.

The important repository containing: