<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CI/CD on Time Friend</title><link>https://time-friend.com/en/tags/ci/cd/</link><description>Recent content in CI/CD on Time Friend</description><generator>Hugo</generator><language>en-GB</language><lastBuildDate>Wed, 29 Jul 2026 15:15:07 +0800</lastBuildDate><atom:link href="https://time-friend.com/en/tags/ci/cd/index.xml" rel="self" type="application/rss+xml"/><item><title>Deploying This Blog: From Push to Live</title><link>https://time-friend.com/en/archive/blog-architecture-deployment/</link><pubDate>Thu, 10 Apr 2025 15:44:00 +0000</pubDate><guid>https://time-friend.com/en/archive/blog-architecture-deployment/</guid><description>&lt;p&gt;Static files need a place to live, accessible from anywhere in the world.&lt;/p&gt;
&lt;h1 id="platform-cloudflare-pages"&gt;Platform: Cloudflare Pages&lt;/h1&gt;
&lt;p&gt;Cloudflare Pages over other platforms, three reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Global CDN&lt;/strong&gt;: edge nodes worldwide, visitors load from nearest location&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero-config HTTPS&lt;/strong&gt;: automatic SSL certificate issuance and renewal&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Free tier&lt;/strong&gt;: enough bandwidth and build minutes for a personal blog&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Setup is simple: create a project in Cloudflare Pages dashboard, link your GitHub repo. Build commands and output directory are controlled in GitHub Actions, no need to configure in the dashboard.&lt;/p&gt;</description></item><item><title>How the Blog Build Pipeline Works</title><link>https://time-friend.com/en/archive/blog-architecture-build-pipeline-pwa/</link><pubDate>Wed, 05 Mar 2025 16:30:00 +0000</pubDate><guid>https://time-friend.com/en/archive/blog-architecture-build-pipeline-pwa/</guid><description>&lt;p&gt;After writing articles, you don&amp;rsquo;t want to deploy them manually every time. The goal of automation is simple: push code and forget about it.&lt;/p&gt;
&lt;p&gt;Two things: turn Markdown into static files and put them on the internet. Plus, automate the whole build process.&lt;/p&gt;
&lt;h1 id="gulp-tasks"&gt;Gulp Tasks&lt;/h1&gt;
&lt;p&gt;Two Gulp tasks running in series:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;series&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;build&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;generate-service-worker&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="build"&gt;build&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;task&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;build&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;gulp&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;pipe&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;shell&lt;/span&gt;([&lt;span style="color:#e6db74"&gt;&amp;#39;hugo --buildFuture --minify&amp;#39;&lt;/span&gt;])));
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;One line. Runs Hugo build, &lt;code&gt;--buildFuture&lt;/code&gt; allows future-dated content, &lt;code&gt;--minify&lt;/code&gt; handles HTML/CSS/JS compression at build time.&lt;/p&gt;</description></item><item><title>Continuous Integration - Code Quality Scanning</title><link>https://time-friend.com/en/archive/continuous-integration-code-quality-scanning/</link><pubDate>Sun, 15 Dec 2019 23:15:00 +0000</pubDate><guid>https://time-friend.com/en/archive/continuous-integration-code-quality-scanning/</guid><description>&lt;p&gt;To facilitate managing company code quality, integrating code quality scanning with continuous integration is an important step.
Currently the company is relatively young, but in just one year, we&amp;rsquo;ve had close to 300 frontend projects.&lt;/p&gt;
&lt;p&gt;With so many frontend projects, how we ensure code quality becomes a very important matter.&lt;/p&gt;
&lt;p&gt;With too many code projects, code review is necessary. But manual code review cannot guarantee efficiency.
Due to differences in individual levels and familiarity with company standards, we cannot guarantee consistent standards across all projects.
Some potential bugs may also be missed.&lt;/p&gt;</description></item><item><title>Continuous Integration - Using GitLab CI for Frontend Project Continuous Integration</title><link>https://time-friend.com/en/archive/continuous-integration-using-gitlab-ci-for-frontend-projects/</link><pubDate>Fri, 20 Sep 2019 23:15:00 +0000</pubDate><guid>https://time-friend.com/en/archive/continuous-integration-using-gitlab-ci-for-frontend-projects/</guid><description>&lt;p&gt;There are many continuous integration platforms on the market. Today I&amp;rsquo;ll introduce GitLab&amp;rsquo;s CI.&lt;/p&gt;
&lt;p&gt;Starting from GitLab 8.0, GitLab CI has been integrated into GitLab.&lt;/p&gt;
&lt;p&gt;Usage is very simple. As long as we create a &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file in the project root directory and add a Runner, we directly integrate GitLab CI.&lt;/p&gt;
&lt;p&gt;Integration method is very simple and convenient. Currently we put a &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file in the front-end scaffold, and every subsequent front-end project can directly integrate GitLab CI according to standards.&lt;/p&gt;</description></item><item><title>Automated Deployment of Hugo, Hexo Blog with Travis CI</title><link>https://time-friend.com/en/archive/automated-deployment-hugo-hexo-blog-with-travis-ci/</link><pubDate>Tue, 20 Nov 2018 16:14:25 +0000</pubDate><guid>https://time-friend.com/en/archive/automated-deployment-hugo-hexo-blog-with-travis-ci/</guid><description>&lt;h1 id="what-is-travis-ci"&gt;What is Travis CI?&lt;/h1&gt;
&lt;p&gt;Travis CI is an online hosted CI service. Using Travis for continuous integration doesn&amp;rsquo;t require setting up your own server. Most importantly, it&amp;rsquo;s free for open source projects.
If company uses gitlab, it also provides corresponding continuous integration services. Won&amp;rsquo;t elaborate here.&lt;/p&gt;
&lt;h1 id="travis-ci-configuration-file"&gt;Travis CI Configuration File&lt;/h1&gt;
&lt;p&gt;Travis requires project root directory must have a &lt;code&gt;.travis.yml&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;When your repository has commits, travis will automatically execute the behaviors you configured below.&lt;/p&gt;</description></item><item><title>Automated Deployment Frontend Code - Using grunt-ftp-deploy</title><link>https://time-friend.com/en/archive/automated-deployment-frontend-code-grunt-ftp-deploy/</link><pubDate>Sun, 14 Jun 2015 23:36:00 +0000</pubDate><guid>https://time-friend.com/en/archive/automated-deployment-frontend-code-grunt-ftp-deploy/</guid><description>&lt;p&gt;Every time after modifying code, need to deploy to remote server, my operation steps are:&lt;/p&gt;
&lt;p&gt;Modify code &amp;ndash;&amp;gt; grunt build &amp;ndash;&amp;gt; Open FileZilla &amp;ndash;&amp;gt; Login ftp server &amp;ndash;&amp;gt; Find local folder &amp;ndash;&amp;gt; Find remote server target folder &amp;ndash;&amp;gt; Select all local files &amp;ndash;&amp;gt; Upload&lt;/p&gt;
&lt;p&gt;Because deploying code, at some times will be particularly frequent. Every time need to repeat the above eight operations. Want to do something, change this.&lt;/p&gt;
&lt;p&gt;Today our protagonist: grunt-ftp-deploy&lt;/p&gt;</description></item><item><title>Annoying AngularJS Annotations - Using grunt-ng-annotate</title><link>https://time-friend.com/en/archive/annoying-angularjs-annotations-grunt-ng-annotate/</link><pubDate>Fri, 12 Jun 2015 23:15:00 +0000</pubDate><guid>https://time-friend.com/en/archive/annoying-angularjs-annotations-grunt-ng-annotate/</guid><description>&lt;p&gt;Angular added dependency injection&lt;/p&gt;
&lt;p&gt;When writing code, roughly written as follows&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;tempController&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$scope&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$http&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$state&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;$timeout&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But such code, after compression will cause a problem.
Function parameters: $scope, $http, $state, $timeout will become: a,b,c,d&lt;/p&gt;
&lt;p&gt;Causing this function cannot find services to inject, because each parameter&amp;rsquo;s naming is strictly required.&lt;/p&gt;
&lt;p&gt;As follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;app&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;controller&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;tempController&amp;#39;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;a&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;b&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;,&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;!-- more --&gt;
&lt;p&gt;To solve this problem, angular supports the following writing:&lt;/p&gt;</description></item></channel></rss>