Skip to content

Commit 9512c90

Browse files
committed
new blog post
1 parent 1397703 commit 9512c90

6 files changed

+234
-47
lines changed

404.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
.container {
77
margin: 10px auto;
88
max-width: 600px;
9-
text-align: center;
9+
text-align: left;
1010
}
1111
h1 {
1212
margin: 30px 0;

_config.yml

+1-39
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,10 @@
1-
# Welcome to Jekyll!
2-
#
3-
# This config file is meant for settings that affect your whole blog, values
4-
# which you are expected to set up once and rarely edit after that. If you find
5-
# yourself editing this file very often, consider using Jekyll's data files
6-
# feature for the data you need to update frequently.
7-
#
8-
# For technical reasons, this file is *NOT* reloaded automatically when you use
9-
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
10-
11-
# Site settings
12-
# These are used to personalize your new site. If you look in the HTML files,
13-
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
14-
# You can create any custom variable you would like, and they will be accessible
15-
# in the templates via {{ site.myvariable }}.
161
title: Siang
172
description: >- # this means to ignore newlines until "baseurl:"
183
Siang Lim - personal site
194
baseurl: "" # the subpath of your site, e.g. /blog
205
url: "https://www.siang.ca" # the base hostname & protocol for your site, e.g. http://example.com
21-
twitter_username: jekyllrb
22-
github_username: jekyll
23-
24-
# Build settings
256
markdown: kramdown
267
theme: minima
278
plugins:
289
- jekyll-feed
29-
30-
include: ["_posts"]
31-
32-
defaults:
33-
- scope:
34-
path: "assets/images"
35-
values:
36-
image: true
37-
38-
# Exclude from processing.
39-
# The following items will not be processed, by default. Create a custom list
40-
# to override the default setting.
41-
# exclude:
42-
# - Gemfile
43-
# - Gemfile.lock
44-
# - node_modules
45-
# - vendor/bundle/
46-
# - vendor/cache/
47-
# - vendor/gems/
48-
# - vendor/ruby/
10+
include: ["_posts"]

_posts/2018-07-18-Deploying-Flask-Docker-Heroku.md renamed to _posts/2018-07-27-Docker-Slycot-Control.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ CMD ["app.py"]
7070
```
7171

7272
# Docker Hub
73-
This Docker container is also available in this [GitHub repo](https://github.com/csianglim/alpine-slycot-control).
73+
This Docker container is also available in this [GitHub repo](https://github.com/csianglim/alpine-slycot-control) or this [DockerHub repo](https://hub.docker.com/r/csianglim/alpine-slycot-control/).
7474

7575
Alternatively, use Docker pull:
7676

@@ -85,10 +85,9 @@ docker run csianglim/alpine-slycot-control
8585
```
8686

8787

88-
89-
9088
# Other known issues
9189
FYI Slycot seems to be really fussy about its dependencies, especially numpy versions. I tried using [abn/scipy-docker-alpine](https://github.com/abn/scipy-docker-alpine) as my base image to avoid compiling numpy, scipy and speed up my Docker builds, but Slycot didn't like it. So if you're having trouble, try the latest numpy and scipy version.
9290

9391
# Conclusion
9492
The `control` library requires scipy and numpy, which are big dependencies, making the final Docker image over 700MB. However, it's very likely we could optimize the Dockerfile further and shrink the container size. A follow-up article will be posted when I figure that out.
93+
[]:
+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
---
2+
layout: blog
3+
title: "Automatically update README.md with Travis-CI"
4+
date: "2018-07-28"
5+
author: ["Siang Lim"]
6+
---
7+
8+
While working on content for the [UBC OpenChemE Initiative](https://opencheme.github.io), I got tired of manually updating the README.md file with new notebooks and decided to look for a more elegant solution.
9+
10+
# Rewriting README.md with new links
11+
The goal is to update `README.md` automatically with links to new Jupyter notebooks whenever we make a commit on GitHub. The readme file feeds into Jekyll/GitHub Pages and generates the website that we see [here](https://opencheme.github.io/CHBE356/).
12+
13+
We'll do this with a bash script that collects the names of all .ipynb files in the Notebooks folder and dump the contents into README.md with the right markdown formatting and nbviewer links. We'll use Travis CI to run the script every time we make a commit on GitHub.
14+
15+
# Bash script
16+
## Skip to [this section](#final-bash-script) if you don't want the details
17+
We'll start by writing a bash script to grab all directories (`*`) in the Notebooks folder, one level up (`..`). Save this script as `deploy.sh` in a folder called `scripts` in your main project folder.
18+
19+
20+
```bash
21+
for d in ../Notebooks/* ; do
22+
echo "$d"
23+
# Do something with files in this folder
24+
done
25+
```
26+
27+
If you run that, you'll see that `$d` prints out the entire path and not just the directory name. After some Googling, I found out how to split the base paths and the name using [parameter expansion](# https://stackoverflow.com/questions/3362920/get-just-the-filename-from-a-path-in-a-bash-script).
28+
29+
```bash
30+
for d in ../Notebooks/* ; do
31+
xpath=${d%/*}
32+
xbase=${d##*/}
33+
xfext=${xbase##*.}
34+
xpref=${xbase%.*}
35+
36+
# Do something with files in this folder
37+
done
38+
```
39+
40+
Now, we want not only the directory, but also all notebook files in a particular directory, so we'll do something like this to loop through the files:
41+
42+
```bash
43+
for d in ../Notebooks/* ; do
44+
xpath=${d%/*}
45+
xbase=${d##*/}
46+
xfext=${xbase##*.}
47+
xpref=${xbase%.*}
48+
49+
echo "$d"
50+
51+
for f in "$d"/*.ipynb; do
52+
fpath=${f%/*}
53+
fbase=${f##*/}
54+
ffext=${fbase##*.}
55+
fpref=${fbase%.*}
56+
57+
echo "$f"
58+
done
59+
60+
done
61+
```
62+
63+
If you run the script and look at the echo outputs, you'll see that we are getting close.
64+
65+
We want to output the directories as Markdown `h1` headings and the files as bullet points. We also want a space between each heading for readibility. Finally, we want to write all this to the README.md file in the root directory.
66+
67+
So here's what we'll do:
68+
69+
```bash
70+
71+
readme_path="../README.md"
72+
73+
for d in ../Notebooks/* ; do
74+
xpath=${d%/*}
75+
xbase=${d##*/}
76+
xfext=${xbase##*.}
77+
xpref=${xbase%.*}
78+
79+
echo "# $xbase" >> "$readme_path"
80+
81+
for f in "$d"/*.ipynb; do
82+
fpath=${f%/*}
83+
fbase=${f##*/}
84+
ffext=${fbase##*.}
85+
fpref=${fbase%.*}
86+
87+
echo "* $fpref" >> "$readme_path"
88+
done
89+
90+
echo -e "\n" >> "$readme_path"
91+
92+
done
93+
94+
```
95+
96+
For the individual files, we want to link to nbviewer directly, and convert spaces to `%20` in the URL. Here's how to do it. The `//` in `${xbase// /%20}` means change all spaces ` ` to `%20`.
97+
98+
99+
```bash
100+
101+
readme_path="../README.md"
102+
nbviewer_path="http://nbviewer.jupyter.org/github/OpenChemE/CHBE356/blob/master/Notebooks"
103+
104+
for d in ../Notebooks/* ; do
105+
xpath=${d%/*}
106+
xbase=${d##*/}
107+
xfext=${xbase##*.}
108+
xpref=${xbase%.*}
109+
110+
echo "# $xbase" >> "$readme_path"
111+
112+
for f in "$d"/*.ipynb; do
113+
fpath=${f%/*}
114+
fbase=${f##*/}
115+
ffext=${fbase##*.}
116+
fpref=${fbase%.*}
117+
118+
echo "* [$fpref]($nbviewer_path/${xbase// /%20}/${fbase// /%20})" >> "$readme_path"
119+
done
120+
121+
echo -e "\n" >> "$readme_path"
122+
123+
done
124+
125+
```
126+
127+
# Final bash script
128+
Almost there. We want to also create a separate 'header' file for our README.md and append the links below it. We will also add `shopt -s nullglob` in case we have [empty folders](https://unix.stackexchange.com/questions/239772/bash-iterate-file-list-except-when-empty
129+
). Here's the final file:
130+
131+
```bash
132+
#!/bin/bash
133+
134+
# a pattern that matches nothing "disappears", rather than treated as a literal string:
135+
# https://unix.stackexchange.com/questions/239772/bash-iterate-file-list-except-when-empty
136+
shopt -s nullglob
137+
138+
# Our paths for the readme file
139+
header_path="../header.md"
140+
readme_path="../README.md"
141+
nbviewer_path="http://nbviewer.jupyter.org/github/OpenChemE/CHBE356/blob/master/Notebooks"
142+
143+
# Copy the header over and add a blank line
144+
cat "$header_path" > "$readme_path"
145+
echo -e "\n" >> "$readme_path"
146+
147+
# https://stackoverflow.com/questions/3362920/get-just-the-filename-from-a-path-in-a-bash-script
148+
for d in ../Notebooks/* ; do
149+
xpath=${d%/*}
150+
xbase=${d##*/}
151+
xfext=${xbase##*.}
152+
xpref=${xbase%.*}
153+
154+
echo "# $xbase" >> "$readme_path"
155+
156+
for f in "$d"/*.ipynb; do
157+
fpath=${f%/*}
158+
fbase=${f##*/}
159+
ffext=${fbase##*.}
160+
fpref=${fbase%.*}
161+
162+
echo "* [$fpref]($nbviewer_path/${xbase// /%20}/${fbase// /%20})" >> "$readme_path"
163+
done
164+
165+
echo -e "\n" >> "$readme_path"
166+
167+
done
168+
```
169+
170+
# Travis CI
171+
We're all done with the bash script at this point. Now for the Travis CI part. Travis CI is integrated with GitHub. The service allows us to run scripts every time we make a commit on GitHub. These scripts could be unit tests or any bash script.
172+
173+
I didn't really understand the value of CI services like Travis CI or Circle CI until I had to implement unit tests for the [UBC Envision](https://www.ubcenvision.com) site to prevent our team members from unintentionally(?) breaking it with bad commits *(to be covered in a separate post)*.
174+
175+
## Set up tokens
176+
We'll need an authentication token from GitHub to allow Travis to make changes to the repository. Run this bash command and save the value of the `token` key on your screen:
177+
178+
```bash
179+
$ curl -u csianglim -d '{"scopes":["public_repo"],"note":"CI"}' https://api.github.com/authorizations
180+
```
181+
182+
Navigate to your project folder and install the `travis` gem
183+
184+
```
185+
$ gem install travis
186+
```
187+
188+
Make sure you're in your project folder, then run this command to encrypt the token. Travis will automatically add it to your .travis.yml file:
189+
190+
```
191+
$ travis encrypt GIT_NAME="Travis CI" --add
192+
$ travis encrypt GIT_EMAIL="[email protected]" --add
193+
$ travis encrypt GH_TOKEN=<token> --add
194+
```
195+
196+
Here's what my .travis.yml file looks like:
197+
198+
```
199+
language: ruby
200+
script:
201+
- bash ./scripts/deploy.sh
202+
branches:
203+
only:
204+
- master
205+
env:
206+
global:
207+
- secure: <encrypted_token>
208+
- secure: <encrypted_token>
209+
- secure: <encrypted_token>
210+
```
211+
212+
Now we just need add a few more lines to our `deploy.sh` script and tell Travis to set up git and push to the repo:
213+
214+
```
215+
# Setup and push to master
216+
git config --global user.email ${GIT_EMAIL}
217+
git config --global user.name ${GIT_NAME}
218+
git checkout master
219+
git add .
220+
git commit --message "Travis $TRAVIS_BUILD_NUMBER: $TRAVIS_COMMIT_MESSAGE"
221+
git remote set-url origin https://${GH_TOKEN}@github.com/OpenChemE/CHBE356.git
222+
git push origin master
223+
```
224+
225+
# Conclusion
226+
I am a big advocate of automation to avoid doing any repetitive and tedious work. Reducing unnecessary human input will allow us to spend time on more important and challenging problems, create consistent workflows for all team members and reduce human errors in the final results.

cv.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ permalink: /cv/
66

77
#### CV
88

9-
CV available [here](https://csianglim.github.io/markdown-cv).
9+
Latest CV available **[here](https://csianglim.github.io/markdown-cv)**.
1010

1111
Source available on [GitHub](https://github.com/csianglim/markdown-cv/blob/gh-pages/index.md), based on the [markdown-cv](https://github.com/elipapa/markdown-cv) template.

index.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ title: Siang
77

88
<img class="profile-pic" src="/assets/images/siang.jpg">
99

10-
I graduated with a degree in [Chemical Engineering](http://chbe.ubc.ca) from UBC Vancouver ([BASc '17](https://apsc.ubc.ca/spotlight/siang-lim)). I'm currently a Process Control Engineer at the [Burnaby Refinery](https://en.wikipedia.org/wiki/Burnaby_Refinery). My hobbies include writing [good (-ish) code](https://github.com/csianglim) and drinking excessive volumes of coffee. I also enjoy hiking (sometimes), napping, waking up late on weekends and binge-watching Netflix on a regular basis.
10+
I graduated with a degree in [Chemical Engineering](http://chbe.ubc.ca) from UBC Vancouver ([BASc '17](https://apsc.ubc.ca/spotlight/siang-lim)). I'm currently a Process Control Engineer at the [Burnaby Refinery](https://en.wikipedia.org/wiki/Burnaby_Refinery). My hobbies include writing [good (-ish) code](https://github.com/csianglim) and drinking excessive volumes of coffee. I also enjoy hiking (sometimes), napping, waking up late and binge-watching Netflix on a regular basis.
1111

12-
In my spare time, I develop open source software and academic resources for the [UBC OpenChemE](https://opencheme.github.io/) initiative. In my other chunk of spare time, I collaborate with UBC researchers and students, including the [BioFoundry](http://www.biofoundry.ca/), the [MathBio Group](https://www.math.ubc.ca/~jfeng/) and the [DAIS lab](http://dais.chbe.ubc.ca) on computational engineering and web development [projects](/portfolio).
12+
In my spare time, I develop open source software and academic resources for the [UBC OpenChemE](https://opencheme.github.io/) initiative. In my recent past, I worked on energy engineering projects at [FortisBC](https://www.fortisbc.com/) and collaborated with UBC researchers, including the [BioFoundry](http://www.biofoundry.ca/), the [MathBio Group](https://www.math.ubc.ca/~jfeng/) and the [DAIS lab](http://dais.chbe.ubc.ca) on computational engineering and web development [projects](/portfolio).
1313

14-
I like solving challenging technical puzzles. I am most interested in problems at the intersection of chemical and biological engineering, software development and computer science. Feel free to [contact me](/contact) by email or add me on [LinkedIn](https://www.linkedin.com/in/c-siang-lim-eit-98535048).
14+
I like working on technical puzzles. I am most interested in challenges at the intersection of chemical & biological engineering, software development and computer science. Feel free to [contact me](/contact) by email or add me on [LinkedIn](https://www.linkedin.com/in/c-siang-lim-eit-98535048).

0 commit comments

Comments
 (0)