Author: @Daning Luo Zhu, this article was first published on the official website of Luo Zhu, has authorized the public account of gold mining developer community for exclusive use, including but not limited to editing, marking the original rights and other rights.
GitHub Action is GitHub’s official CI/CD tool. It is lighter weight and easier to scale than Travis CI and Circle CI, and there are a lot of community-contributed plugins in the Marketplace. Major open source projects, such as Deno, are turning to GitHub Action as a continuous integration tool.
Many of the GitHub documentation is written in obscure terms, and some translations are too rigid to understand. As of press time, Deno’s ci.yml file is 323 lines long and a good example to learn. Those who want to know more about GitHub Action or are interested in Deno’s continuous integration section can explore it together.
The Action structure
Note: Ci scripts for GitHub actions need to be placed in the.github/workflows folder
name: ci
on: [push.pull_request]
jobs:
Copy the code
name
: The name of the workflow. GitHub displays the name of the workflow on the repository’s operations page. If the name is omitted, GitHub sets it to the workflow file path relative to the repository root.on
: required. isThe event that triggers the workflow. Deno in the[push,pull_request]
The CI process is triggered when there is a primary branch with a submit code or pull_request.jobs
Workflow operation consists of one or more jobs. Jobs run in parallel by default. There is only one job in Denobuild
build job
jobs:
build:
name: The ${{ matrix.kind }} The ${{ matrix.os }}
if: | github.event_name == 'push' || ! startsWith(github.event.pull_request.head.label, 'denoland:') runs-on: The ${{ matrix.os }}
timeout-minutes: 60
strategy:
#...
env:
#...
steps:
#...
Copy the code
- ‘name: The name by which the assignment appears on GitHub.
matrix
: used to access the matrix parameters configured for the current job. For example, Deno is built using the Kind and OS version configuration matrix, and the Matrix context object will contain the Kind and OS versions of the current job.
if
: You can use an if condition to prevent a job from running until the condition is met. Deno in judgmentgithub.event_name
Is equal to the"push"
或label
以"denoland:"
At the beginning ofpull_request
The eventruns-on
:mandatory. The machine on which the task runs. The machine can be either a GitHub hosted runner or a self-hosted runner. When defining the operating system matrix, you mustruns-on
Is set to the value you definematrix.os
Context properties. Deno is cross-platform, so matrices are created to run build workflows on multiple runner operating systems.timeout-minutes
: The maximum number of minutes a job can run before GitHub automatically cancals it. Default value: 360. Set it to 60 in Deno to expose problems early.strategy
: policy to create a build matrix for the job. You can define different variations of each job to run in. This may not be easy to understand, but in Deno, it’s all about building multiple platforms at once. The specific applications of Deno are discussed separately in the following sections.env
: of an environment variablemap
Can be used for all steps in a job. You can also set environment variables for the entire workflow or for individual steps. The specific applications of Deno are discussed separately in the following sections.steps
: The assignment consists of a series of tasks called steps. Steps can run commands, run setup tasks, or run operations in your repository, public repository, or published operations in the Docker registry. The specific applications of Deno are discussed separately in the following sections.
The strategy strategy
strategy:
matrix:
include:
- os: Macos 10.15
kind: test_release
- os: windows-2019
kind: test_release
- os: The ${{ github.repository = = 'denoland/deno' && 'ubuntu-latest' || 'ubuntu-18.04' }}
kind: test_release
- os: The ${{ github.repository = = 'denoland/deno' && 'ubuntu-latest' || 'ubuntu-18.04' }}
kind: test_debug
- os: The ${{ github.repository = = 'denoland/deno' && 'ubuntu-latest' || 'ubuntu-18.04' }}
kind: bench
- os: The ${{ github.repository = = 'denoland/deno' && 'ubuntu-latest' || 'ubuntu-18.04' }}
kind: lint
# Always run master branch builds to completion. This allows the cache to
# stay mostly up-to-date in situations where a single job fails due to
# e.g. a flaky test.
# Don't fast-fail on tag build because publishing binaries shouldn't be
# prevented if 'cargo publish' fails (which can be a false negative).
fail-fast: The ${{ github.event_name = = 'pull_request' || (github.ref ! =
'refs/heads/master' && ! startsWith(github.ref, 'refs/tags/')) }}
Copy the code
strategy
The: policy creates a build matrix for your work. You can define different variations to run each job. This may not be easy to understand, but in Deno, it’s all about building multiple platforms at once.matrix
: You can define a matrix for different job configurations. There are six matrices defined in Deno. They are used to test, debug, load, lint, and so oninclude
Use:matrix
Only one OS can be defined, and no other configuration can be added. withinclude
Can solve this problem
fail-fast
: set totrue
If anymatrix
If the job fails, GitHub will cancel all ongoing jobs. Default value:true
. Ry in thiscommitremovedcargo publish
From the comment herefail-fast
The configuration is already redundant, I just have a fork, commit,pr3 even.
episode
= = ‘${{making. The repository denoland/deno’ && ‘ubuntu – latest’ | | ‘ubuntu 18.04’}} this writing I wondered when I see, can’t directly take ‘ubuntu – latest? If not, why not? With a realistic attitude, I read the judgment that was added in the commit, and after questioning, I got the following answer:
Here’s justjavac:
Then I have a question as to why not use ternary expressions, is it that YAML syntax does not support it?
Maybe it is my grammar is wrong, do not use according to JS experience, the big guy who knows can comment teaching!
Env Environment variable
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: full
CARGO_TERM_COLOR: always
Copy the code
env
: of an environment variablemap
Can be used for all steps in a job. You can also set environment variables for the entire workflow or for individual steps. The three variables in the code are environment variables for the entire process.CARGO_INCREMENTAL
,CARGO_TERM_COLOR
,RUST_BACKTRACE
It is configured for Cargo, for referenceenvironment-variables-cargo-readsI won’t read it here.
Steps steps
Deno’s CI has 35 steps by the time I write this paragraph, which tests my courage to continue reading…
The job consists of a series of tasks called steps. Steps can run commands, run setup tasks, or run operations in your repository, public repository, or published operations in the Docker registry. Not all steps will run operations, but all operations will run as steps. Each step runs as its own process in the runtime environment and has access to the workspace and file system. Because the steps run as their own process, no environment variable changes are retained between steps. GitHub provides built-in steps to set up and complete the job. – document
1, the Configure git
- name: Configure git
run: git config --global core.symlinks true
Copy the code
git config --global core.symlinks true
: Clone a repository containing submodules and symbolic links. This is for Windows compatibility, please see the detailed explanationgit bash symbolic links on windows
2, Clone the repository
- name: Clone repository
uses: actions/checkout@v2
with:
Use 'depth> 1', because sometimes we need to rebuild the master branch, and if the COMMITS are too shallow, other commits will not be able to rebuild later.
fetch-depth: 5
submodules: true
Copy the code
actions/checkout@v2
The: checkout action is often usedfetch-depth: 5
: By default, only one commit is extracted. If I set 5 here, the last 5 commits will be extracted.submodules: true
The submodule is included in Deno.
3, Create source tarballs (release, Linux)
Create source file compression package (Release, Linux)
- name: Create source tarballs (release, linux)
if: | startsWith(matrix.os, 'ubuntu') && matrix.kind == 'test_release' && github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') run: | mkdir -p target/release tar --exclude=.cargo_home --exclude=".git*" --exclude=target --exclude=third_party/prebuilt -czvf target/release/deno_src.tar.gz -C .. denoCopy the code
- Execution condition: Build matrix OS is
'ubuntu'
, kind is'test_release'
, warehouse is'denoland/deno'
, local executiongit push --tags
或Git push origin v0.0.1
run
In fact, the source file is automatically packaged when releasing the release. The reason for this is that we need to ignore many folders and type the pure deno source file
4, Install rust
Install the rust
- name: Install rust
uses: hecrj/setup-rust-action@v1
with:
rust-version: 1.49. 0
Copy the code
- The Deno source code was written by RUST, so it is used
hecrj/setup-rust-action@v1
Each language has its ownsetup
You can find it in stores358Records.
5. Install Clippy and rustfmt
- name: Install clippy and rustfmt
if: matrix.kind = = 'lint'
run: | rustup component add clippy rustup component add rustfmtCopy the code
6, Install Deno (non-Windows)
- name: Install Deno
if: |! startsWith(matrix.os, 'windows') run: | | - curl - fsSL https://deno.land/x/install/install.sh sh -s v1.5.1 echo "$HOME /. Deno/bin" > > $GITHUB_PATHCopy the code
- Execution condition: Build matrix OS is not Windows
run
|-
和|
Is the syntax of YAML. This way, you can effectively declare multi-line YAML strings. Syntax detailsHere,The curl - fsSL https://deno.land/x/install/install.sh | sh - s v1.5.1
Install deno (should be able to pr here)echo "$HOME/.deno/bin" >> $GITHUB_PATH
: sets the environment variable, which should be present for any new environment variable that points to a location on the file system_PATH
The suffix.
7, Install Deno (Windows)
- name: Install Deno (Windows)
if: startsWith(matrix.os, 'windows')
run: | | - curl - fsSL https://deno.land/x/install/install.sh sh -s v1.5.1 echo "$HOME /. Deno/bin" > > $env: GITHUB_PATHCopy the code
- Execution condition: Build matrix OS is Windows
run
: Same as above
8, Install Python
Install python
- name: Install Python
uses: actions/setup-python@v1
with:
python-version: '3.8'
architecture: x64
Copy the code
9, Install the Node
Install the Node
- name: Install Node
uses: actions/setup-node@v2
with:
node-version: '14'
check-latest: true
Copy the code
10, Remove unused versions of Python
Remove Python versions that are not in use
- name: Remove unused versions of Python
if: startsWith(matrix.os, 'windows')
run: |- $env:PATH -split ";" | Where-Object { Test-Path "$_\python.exe" } | Select-Object -Skip 1 | ForEach-Object { Move-Item "$_" "$_.disabled" }Copy the code
11, Setup gCloud (Unix)
Install the Google Cloud SDK (Unix)
- name: Setup gcloud (unix)
if: | runner.os ! = 'Windows' && matrix.kind == 'test_release' && github.repository == 'denoland/deno' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')) uses: google-github-actions/setup-gcloud@master
with:
project_id: denoland
service_account_key: The ${{ secrets.GCP_SA_KEY }}
export_default_credentials: true
Copy the code
- Execution conditions: Running system is not ‘Windows’, building matrix kind is
'test_release'
, warehouse is'denoland/deno'
, branch is either master or tag commit google-github-actions/setup-gcloud
A collection of GitHub Actions that interact with the Google Cloud Platform.
Setup GCloud (Windows)
Same as 11, but set up GCloud for Windows
- name: Setup gcloud (windows)
if: | runner.os == 'Windows' && matrix.kind == 'test_release' && github.repository == 'denoland/deno' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')) uses: google-github-actions/setup-gcloud@master
env:
CLOUDSDK_PYTHON: ${{env.pythonLocation}}\python.exe
with:
project_id: denoland
service_account_key: The ${{ secrets.GCP_SA_KEY }}
export_default_credentials: true
Copy the code
13, Configure canary build
Configure the build of the Canary channel (Deno Release atmosphere Canary and Release channel)
- name: Configure canary build
if: | matrix.kind == 'test_release' && github.repository == 'denoland/deno' && github.ref == 'refs/heads/master' shell: bash
run: | echo "DENO_CANARY=true" >> $GITHUB_ENVCopy the code
- Execution condition: Build matrix
kind
为'test_release'
, making repo is'denoland/deno'
And the master branch run
将"DENO_CANARY=true"
Set into the environment variable.
You can also use the GITHUB_ENV environment file to set environment variables that can be used in the following steps in the workflow. – document
14 and the Log versions
Check the version of the previously installed program
- name: Log versions
run: | node -v python --version rustc --version cargo --version deno --versionCopy the code
15, lint. Js
Perform lint
- name: lint.js
if: matrix.kind = = 'lint'
run: deno run --unstable --allow-write --allow-read --allow-run ./tools/lint.js
Copy the code
- Execution condition: Build matrix
kind
A type of'lint'
16, test_format. Js
Test formatter
- name: test_format.js
if: matrix.kind = = 'lint'
run: deno run --unstable --allow-write --allow-read --allow-run ./tools/format.js --check
Copy the code
- Execution condition: Build matrix
kind
A type of'lint'
17, the Build release
- name: Build release
if: | matrix.kind == 'test_release' || matrix.kind == 'bench' run: cargo build --release --locked --all-targets -vv
Copy the code
- Execution condition: Build matrix
kind
A type of'test_release'
或'bench'
18, Build the debug
- name: Build debug
if: matrix.kind = = 'test_debug'
run: cargo build --locked --all-targets
Copy the code
- Execution condition: Build matrix
kind
A type of'test_debug'
19, Pre – release (Linux)
Preparations before release (Linux)
- name: Pre-release (linux)
if: | startsWith(matrix.os, 'ubuntu') && matrix.kind == 'test_release' run: | cd target/release zip -r deno-x86_64-unknown-linux-gnu.zip deno zip -r denort-x86_64-unknown-linux-gnu.zip denort ./deno types > lib.deno.d.tsCopy the code
- Execution condition: construct matrix OS is
'ubuntu'
, build matrixkind
为'test_release'
run
: All it does is create a zip package that will eventually be released in the GitHub Release for the installation script
20, Pre – release (MAC)
/deno types > lib.deno.d.ts./deno types > lib.deno.d.ts
- name: Pre-release (mac)
if: | startsWith(matrix.os, 'macOS') && matrix.kind == 'test_release' run: | cd target/release zip -r deno-x86_64-apple-darwin.zip deno zip -r denort-x86_64-apple-darwin.zip denortCopy the code
21, the Pre – release (Windows)
And 19, 20, just for Windows, you can learn the Windows compression command how to write!
- name: Pre-release (windows)
if: | startsWith(matrix.os, 'windows') && matrix.kind == 'test_release' run: | Compress-Archive -CompressionLevel Optimal -Force -Path target/release/deno.exe -DestinationPath target/release/deno-x86_64-pc-windows-msvc.zip Compress-Archive -CompressionLevel Optimal -Force -Path target/release/denort.exe -DestinationPath target/release/denort-x86_64-pc-windows-msvc.zipCopy the code
22, Upload a canary to dL.deno. land (Unix)
Upload the Canary package to DL-deno. land (Unix) (we just need to know that it’s hosted in the Google Cloud)
- name: Upload canary to dl.deno.land (unix)
if: | runner.os ! = 'Windows' && matrix.kind == 'test_release' && github.repository == 'denoland/deno' && github.ref == 'refs/heads/master' run: | gsutil cp ./target/release/*.zip gs://dl.deno.land/canary/$(git rev-parse HEAD)/ echo $(git rev-parse HEAD) > canary-latest.txt gsutil cp canary-latest.txt gs://dl.deno.land/canary-latest.txtCopy the code
- Execution condition: The operating system is not Windows, build matrix kind is
'test_release'
, making repo is'denoland/deno'
And the master branch run
gsutil cp ./target/release/*.zip gs://dl.deno.land/canary/$(git rev-parse HEAD)/
: Uploads the compressed package to the server$(git rev-parse HEAD)
: Get the latest Git Commit hash, which you can execute in any Git repositoryecho $(git rev-parse HEAD)
validation
echo $(git rev-parse HEAD) > canary-latest.txt
: writes the commit hash value as the version to canary-latest. TXTgsutil cp canary-latest.txt gs://dl.deno.land/canary-latest.txt
Upload:canary-latest.txt
To the server
23, Upload a canary to dL.deno. land (Windows)
Same as 22, just for Windows
- name: Upload canary to dl.deno.land (windows)
if: | runner.os == 'Windows' && matrix.kind == 'test_release' && github.repository == 'denoland/deno' && github.ref == 'refs/heads/master' env:
CLOUDSDK_PYTHON: ${{env.pythonLocation}}\python.exe
shell: bash
run: | gsutil cp ./target/release/*.zip gs://dl.deno.land/canary/$(git rev-parse HEAD)/ echo $(git rev-parse HEAD) > canary-latest.txt gsutil cp canary-latest.txt gs://dl.deno.land/canary-latest.txtCopy the code
CLOUDSDK_PYTHON: ${{env.pythonLocation}}\python.exe
: You can see here that the Python environment is for the Google Cloud SDK
24, the Test release
The test release
- name: Test release
if: matrix.kind = = 'test_release'
run: cargo test --release --locked --all-targets
Copy the code
25, Test, debug
Test the debug
- name: Test debug
if: matrix.kind = = 'test_debug'
run: | cargo test --locked --doc cargo test --locked --all-targetsCopy the code
26, Configure hosts file for WPT (Unix)
26, Configure hosts file for WPT (Unix)
WPT stands for Web Platform Test, which corresponds to denoland/ WPT
- name: Configure hosts file for WPT (unix)
if: runner.os ! = 'Windows'
run: ./wpt make-hosts-file | sudo tee -a /etc/hosts
working-directory: test_util/wpt/
Copy the code
27, Configure hosts file for WPT (Windows)
Same as 26, just for Windows
- name: Configure hosts file for WPT (windows)
if: runner.os = = 'Windows'
working-directory: test_util/wpt/
run: python wpt make-hosts-file | Out-File $env:SystemRoot\System32\drivers\etc\hosts -Encoding ascii -Append
Copy the code
28, Run Web platform tests (release)
Running tests on a Web platform (Release)
- name: Run web platform tests (release)
if: matrix.kind = = 'test_release'
run: | deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts setup deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts run --quiet --releaseCopy the code
29, Run web platform tests (debug)
Running tests on the Web platform (Debug)
- name: Run web platform tests (debug)
if: matrix.kind = = 'test_debug'
run: | deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts setup deno run --unstable --allow-write --allow-read --allow-net --allow-env --allow-run ./tools/wpt.ts run --quietCopy the code
30, Run Benchmarks
Pressure test
- name: Run Benchmarks
if: matrix.kind = = 'bench'
run: cargo bench
Copy the code
- Execution condition: build matrix kind is
'bench'
31, Post Benchmarks
It looks like the pressure test data is stored in denoland/benchmark_data
- name: Post Benchmarks
if: | matrix.kind == 'bench' && github.repository == 'denoland/deno' && github.ref == 'refs/heads/master' env:
DENOBOT_PAT: The ${{ secrets.DENOBOT_PAT }}
run: | git clone --depth 1 -b gh-pages https://${DENOBOT_PAT}@github.com/denoland/benchmark_data.git gh-pages deno run --unstable -A ./tools/build_benchmark_jsons.js --release cd gh-pages git config user.email "[email protected]" git config user.name "denobot" git add . git commit --message "Update benchmarks" git push origin gh-pagesCopy the code
- Execution conditions:
denoland/deno
The master branch of the library and the kind that builds the matrix is'bench'
32, the Worker info
- name: Worker info
if: matrix.kind = = 'bench'
run: | cat /proc/cpuinfo cat /proc/meminfoCopy the code
- Execution condition: build matrix kind is
bench
- run
cat /proc/cpuinfo
: Displays CPU informationcat /proc/meminfo
: Displays memory information
Upload release to dL.deno.land (Unix)
Upload the Unix release to dL.deno.land
- name: Upload release to dl.deno.land (unix)
if: | runner.os ! = 'Windows' && matrix.kind == 'test_release' && github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') run: | gsutil cp ./target/release/*.zip gs://dl.deno.land/release/${GITHUB_REF#refs/*/}/ echo ${GITHUB_REF#refs/*/} > release-latest.txt gsutil cp release-latest.txt gs://dl.deno.land/release-latest.txtCopy the code
34, Upload release to dL.deno. land (Windows)
Upload Windows Release to dL.deno.land
- name: Upload release to dl.deno.land (windows)
if: | runner.os == 'Windows' && matrix.kind == 'test_release' && github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') env:
CLOUDSDK_PYTHON: ${{env.pythonLocation}}\python.exe
shell: bash
run: | gsutil cp ./target/release/*.zip gs://dl.deno.land/release/${GITHUB_REF#refs/*/}/ echo ${GITHUB_REF#refs/*/} > release-latest.txt gsutil cp release-latest.txt gs://dl.deno.land/release-latest.txtCopy the code
Upload release to GitHub
Upload the release to GitHub
- name: Upload release to GitHub
uses: softprops/action-gh-release@v1
if: | matrix.kind == 'test_release' && github.repository == 'denoland/deno' && startsWith(github.ref, 'refs/tags/') env:
GITHUB_TOKEN: The ${{ secrets.GITHUB_TOKEN }}
with:
files: | target/release/deno-x86_64-pc-windows-msvc.zip target/release/deno-x86_64-unknown-linux-gnu.zip target/release/deno-x86_64-apple-darwin.zip target/release/deno_src.tar.gz target/release/lib.deno.d.ts draft: true
Copy the code
softprops/action-gh-release@v1
: Github Release action. This is a great way to do advanced actions such as directly uploading a Release asset. I am intuya-panel-demoThe plug-in is used in
Doodle Smart has a large number of high-quality HC, welcome to join, you need to add my wechat yang_jun_ning, or directly send your resume to [email protected]