Migrate My Blog From Ghost to Hexo

Why

Last time I updated my blog was about 10 months ago. My blog used to be hosted on my own linux vps. I setup the machine, nginx, nodejs, ghost and the blog. It was fun to put all those things together and enjoy my final product, my blog. But I’m not a real blogger. You see I haven’t update it for a long time. And I still have to pay for the vps, domain, and maintain the ‘system’, not the blog itself.

Github pages is free to host static pages, also coming with a free domain name. And hexo is easy to let you build your static blog. BTW, it’s on node.js :) It actually only spent me a short time to migrate my blog from my own vps to github.

How

  • backup existing ghost data to json file
  • install hexo local
  • import ghost data using hexo-migrator-ghost
  • test on local
  • generate static pages
  • deploy blog to github.io

Issue in Npm v5.4.0 Which Doesn't Work With Flow Check - Error: Spawn EACCES

Error

4th Sep 2017, Monday. All our node.js builds failed with below error at the step when we run flow check

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> flow check

internal/child_process.js:315
throw errnoException(err, 'spawn');
^

Error: spawn EACCES
at exports._errnoException (util.js:907:11)
at ChildProcess.spawn (internal/child_process.js:315:11)
at exports.spawn (child_process.js:365:9)
at Object.<anonymous> (/opt/app/node_modules/flow-bin/cli.js:17:3)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:140:18)

Cause

First thought it was a flow error of latest version. Downgrade ‘flow-bin’ to previous version didn’t work. It was actually caused by ‘spawn’ calling files with incorrect permissions. internal/child_process.js:315 throw errnoException(err, 'spawn');
NPM v5.4.0 removes executable(+x) permission during installing packages.

Solution

fix npm to v5.3.0 works npm install npm@5.3.0


It’s still an open issue in NPM when I wrote this.
https://github.com/npm/npm/issues/18324

Promise.coroutine

Promise.coroutine(GeneratorFunction(…arguments) generatorFunction, Object options) -> function

When called, the coroutine function will start an instance of the generator and returns a promise for its final value.

Doing Promise.coroutine is almost like using the C# async keyword to mark the function, with yield working as the await keyword. Promises are somewhat like Tasks.

The async/await key words are already available in es2017 and node 8.

Reference
http://bluebirdjs.com/docs/api/promise.coroutine.html

乌兰巴托的夜

Улаанбаатарын удэш 乌兰巴托原称库伦,是蒙古的首都,意为“红色英雄”。歌曲创作于1985年,由蒙古诗人桑堆扎布(P.Sanduyjav)作词,普勒布道尔吉(G.Pürevdorj)作曲。

清白之年

此生多勉强,此身越重洋,轻描时光漫长,低唱语焉不详。

故事开始以前 最初的那些春天 阳光洒在杨树上 风吹来 闪银光 街道平静而温暖 钟走得好慢 那是我还不识人生之味的年代

我情窦还不开
你的衬衣如雪
盼着杨树叶落下 眼睛不眨
心里像有一些话
我们先不讲
等待着那将要盛装出场的未来

人随风飘荡
天各自一方
在风尘中遗忘的清白脸庞
此生多勉强
此身越重洋
轻描时光漫长低唱语焉不详

数不清的流年
似是而非的脸
把你的故事对我讲
就让我笑出泪光
是不是生活太艰难
还是活色生香
我们都遍体鳞伤
也慢慢坏了心肠
你得到你想要的吗
换来的是铁石心肠
可曾还有什么人
再让你幻想

大风吹来了
我们随风飘荡
在风尘中遗忘的清白脸庞
此生多寒凉
此身越重洋
轻描时光漫长低唱语焉不详

大风吹来了
我们随风飘荡
在风尘中熄灭的清澈目光
我想回头望
把故事从头讲
时光迟暮不返人生已不再来


这首歌朴树本来是委托高晓松为之作词的,高晓松写了一稿,两个人都觉得不好,就没有采用。直到专辑出来后,高晓松听到这首《清白之年》,感慨道:

写的真好,比我写的好。此生多勉强,此身越重洋,轻描时光漫长,低唱语焉不详。这个我写不出来,这个就是朴树。这个就是他的那种特别神奇的中文的感觉。因为他不是那种读过万卷书,背过十三韵,靠底子写东西的人,他全靠燃烧。每当燃烧的时候,能把中文燃烧成一种崭新的语言、句法,这个非常难。所以他才花这么多年做一张专辑,因为燃烧这个事情不是随时随地就能发生,需要积累很久才能燃烧一把。

Use CODEOWNERS to Receive Code Review Automatically

In my current project, we are not allowed to commit to master directly. Everyone has to create a pull request first, pass all the automation checks, then a code review is also required. Everytime, the pull request creator has to select all the team members one by one to add them into the reviewers list one the right panel on github page. It’s a bit annoying and time consuming.

Using CODEOWNERS file, code owners are automatically requested for code review when pull request created.

Just create a new file called CODEOWNERS in the root or .github/ folder.

Example file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# This is a comment.
# Each line is a file pattern followed by one or more owners.

# These owners will be the default owners for everything in the repo.
# Unless a later match takes precedence, @global-owner1 and @global-owner2
# will be requested for review when someone opens a pull request.
* @global-owner1 @global-owner2

# Order is important; the last matching pattern takes the most precedence.
# When someone opens a pull request that only modifies JS files, only @js-owner
# and not the global owner(s) will be requested for a review.
*.js @js-owner

# You can also use email addresses if you prefer. They'll be used to look up
# users just like we do for commit author emails.
docs/* docs@example.com

Reference
https://help.github.com/articles/about-codeowners/

Really Beyond the Cloud

I’m really beyond the cloud now, flying with China Southern Airline. It’s the first time I use internet on an airplane. They provide internet service on the plane for non mobile devices, like laptop or tablet.

Customise Aws API Gateway Name in Serverless Framework

serverless framework

When using serverless framework to deploy aws api gateway, by default the api name will be stage-servicename, like sit-test-service or dev-test-service.

If you want to customise the api name, you can do it through resources configuration.

1
2
3
4
5
6
7
8
serverless.yml

resources:
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: "yourServiceName"

I use a seperate resource file, it looks like this

1
2
3
4
serverless.yml

resources:
Resources: ${file(resources.yml)}
1
2
3
4
5
6
resources.yml

ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: "yourServiceName"
  • When you deploy again after adding custom api name, serverless will call aws cloudformation update-stack based on the cloudformation json template. It won’t create a new api, just rename it by updating the existing api. The existing api id won’t change, so the existing cloudfront or custom dns won’t be affected.

CLI

if you want to do this via command line,

  • first list APIS and IDs under your account:
1
aws apigateway get-rest-apis
  • Use the Id to update name of API
1
aws apigateway update-rest-api --rest-api-id IDOfTheAPIThatNeedsTobeUpdated --patch-operations op=replace,path=/name,value=NewName