跳转至

博客

Github Actions 全指南

Understanding GitHub Actions - GitHub Docs 中,Github Actions 是被这样描述的:

「Github Actions 是能够让你自动化构建、测试、部署流程的一个 CI/CD 平台」

其中有一个词 CI/CD,持续集成(Continuous Integration)/持续交付(Continuous Delivery),网络上对于他们的定义如下:

  • CI:多名开发者开发不同功能代码的过程中,可以频繁地将代码合并到一起且不影响相互的工作

  • CD:在对代码的自动化构建、测试、部署的基础上,将产品交付到线上生产环境。

简单地来讲,Github Actions 可以在仓库有新的事件发生(新的 Commit / 新的 Pull Request / 新的 Tag 等等)时按照配置文件自动化地执行一些工作,比如代码的测试、构建,甚至可以自动发表 Release。

一、Github Actions 的组成

Diagram of an event triggering Runner 1 to run Job 1, which triggers Runner 2 to run Job 2. Each of the jobs is broken into multiple steps.

workflow

被事件触发的一系列操作被称作 workflow

一个 workflow 包含一个或多个 job(可以并行或串行执行)

每个 job 会在一个 runner 上运行,runner 本质类似于一个虚拟机

每个 job 包含一个或多个 step

在每个 step 中可以运行脚本/终端命令或其他的 action

events

pattern
  • *:匹配零个或多个字符,但是不匹配 /
  • **:匹配零个或多个任意字符
  • ?+[] 类似正则表达式

实例

1. 自动构建、发布 golang 程序

GoReleaser:自动化你的软件发布 | 简体中文博客 (nsddd.top)

使用 clog-cli 由 git 提交生成 changelog

https://github.com/clog-tool/clog-cli

https://github.com/conventional-changelog/conventional-changelog/blob/a5505865ff3dd710cf757f50530e73ef0ca641da/conventions/angular.md

clog 能够使用本地 git 仓库的信息自动生成 changelog:

image-20230927135701954

只需要确保你的每一次提交都满足 conventional 格式,之后在希望更新 changelog 的时候只需要简单地运行 clog 即可。

可以通过一个 .clog.toml 文件来配置,以下为默认配置:

TOML
[clog]
# A repository link with the trailing '.git' which will be used to generate
# all commit and issue links
repository = "https://github.com/clog-tool/clog-cli"
# A constant release title
subtitle = "my awesome title"

# specify the style of commit links to generate, defaults to "github" if omitted
link-style = "github"

# The preferred way to set a constant changelog. This file will be read for old changelog
# data, then prepended to for new changelog data. It's the equivilant to setting
# both infile and outfile to the same file.
#
# Do not use with outfile or infile fields!
#
# Defaults to stdout when omitted
changelog = "mychangelog.md"

# This sets an output file only! If it exists already, new changelog data will be
# prepended, if not it will be created.
#
# This is useful in conjunction with the infile field if you have a separate file
# that you would like to append after newly created clog data
#
# Defaults to stdout when omitted
outfile = "MyChangelog.md"

# This sets the input file old! Any data inside this file will be appended to any
# new data that clog picks up
#
# This is useful in conjunction with the outfile field where you may wish to read
# from one file and append that data to the clog output in another
infile = "My_old_changelog.md"

# This sets the output format. There are two options "json" or "markdown" and
# defaults to "markdown" when omitted
output-format = "json"

# If you use tags, you can set the following if you wish to only pick
# up changes since your latest tag
from-latest-tag = true

「Mac」Yabai 窗口管理器

Note

​ 本篇文章中所用设备为 MacBook Pro M2 Max。

Banner

screenshot.png

Yabai 是一个 Mac 下的平铺窗口管理器,它作为 MacOS 内置的窗口管理器的扩展运行,可以使得窗口、空间、显示控制变得十分高效。

Github:koekeishiya/yabai: A tiling window manager for macOS based on binary space partitioning (github.com)

一、安装

1. 关闭 SIP

自 MacOS 10.13 起,一个叫做 系统完整性保护(System Integrity Protection)的功能被引入,它会保护一些特定的文件和目录不被修改(即便以 root 用户的身份)。

而 Yabai 的如下功能会需要向 Dock.app 中注入一些脚本:

  • 工作空间的 聚焦、移动、切换、创建、销毁
  • 移除窗口阴影
  • 启用窗口透明
  • 启用窗口动画
  • 控制窗口层级(比如置顶某一窗口)
  • 粘性窗口(使某一个窗口在所有工作空间显示)

所以,为了这些功能,首先我们需要关闭 SIP:

  1. 关机

  2. 长按关机键直至显示“Loading startup options”,然后点击“选项”,再点击“继续”

  3. 于菜单栏中选择 Utilities 然后选择 Terminal

  4. 运行如下命令来部分关闭 SIP:

Bash
csrutil enable --without fs --without debug --without nvram
  1. 重启

  2. 运行如下命令启用非苹果签名的 arm64e 可执行文件

Text Only
sudo nvram boot-args=-arm64e_preview_abi
  1. 再重启

可以通过 csrutil status 来查看 SIP 的状态。

如果想要再启用 SIP,重复上面的步骤并在第4步执行 cstutil enable 即可

2. 安装 Yabai

Bash
brew install koekeishiya/formulae/yabai

然后配置注入脚本:

Bash
# create a new file for writing - visudo uses the vim editor by default.
# go read about this if you have no idea what is going on.

sudo visudo -f /private/etc/sudoers.d/yabai

# input the line below into the file you are editing.
#  replace <yabai> with the path to the yabai binary (output of: which yabai).
#  replace <user> with your username (output of: whoami). 
#  replace <hash> with the sha256 hash of the yabai binary (output of: shasum -a 256 $(which yabai)).
#   this hash must be updated manually after running brew upgrade.

<user> ALL=(root) NOPASSWD: sha256:<hash> <yabai> --load-sa

再编辑 yabairc 配置文件(~/.yabairc):

Bash
1
2
3
4
5
6
7
# for this to work you must configure sudo such that
# it will be able to run the command without password

yabai -m signal --add event=dock_did_restart action="sudo yabai --load-sa"
sudo yabai --load-sa

# .. more yabai startup stuff

使用 yabai --start-service 来启动。

3. 配置

Yabi 提供了很多命令,比如:

见:Commands · koekeishiya/yabai Wiki (github.com)

  • yabair -m config 进行一些选项的设定,

  • yabai -m display/space/windows xxx 来对显示器/工作空间/窗口进行调整

  • yabai -m query xxx 来获取一些当前 Yabai 中窗口等东西的信息
  • yabai -m rule 来添加窗口规则
  • yabai -m signal 来添加时间监听

而前面的 .yabairc 实际上是一个脚本,其中的内容会在每次 Yabai 启动的时候运行,那么就可以通过 yabai -m config 来在其中设置相关的选项。

见:Configuration · koekeishiya/yabai Wiki (github.com)

而对于快捷键则需要安装 koekeishiya/skhd: Simple hotkey daemon for macOS (github.com),其配置文件 .skhdrc 中包含了按键到命令的绑定,也就是说在其中可以通过其他的命令来实现各种快捷键的功能。

见:yabai/examples/skhdrc at master · koekeishiya/yabai (github.com)

修改 VSCode UI 界面字体

image-20230824111944843

安装 fonted 插件,在设置中配置想要替换的字体,然后 Ctrl Shift p 在 command pallette 中执行 Fonted: Enable 重启编辑器即可。

mermaid 甘特图渲染过小踩坑记录

在折腾 MkDocs + Material for MkDocs 里的 Mermaid 渲染时,发现如果直接按照 Material for MkDocs 文档1来做,那么甘特图内容时间跨度较大、宽度较长时会被渲染得很小(甚至包括 Mermaid 的官方文档2也是这样)

image-20230815154258622

用 Markdown 代替 ppt —— 使用 Slidev 制作演示文稿

image-20230701134009108

一、概述

Slidev 是一款基于 Web 的幻灯片制作和演示工具。它旨在让开发者专注在 Markdown 中编写内容,同时拥有支持 HTML 和 Vue 组件的能力,并且能够呈现像素级完美的布局,还在你的演讲稿中内置了互动的演示样例。

它使用了功能丰富的 markdown 文件来生成精美的幻灯片,具有即时重载的体验。它还拥有很多内置的集成功能,如实时编码、导出 PDF、演讲录制等。由于 Slidev 是由 web 驱动的,因此你可以使用它进行任何操作 —— 具有无限的可能性。

编译原理 0. 概述

忽略掉预处理以及链接的部分,C/C++ 语言的完整编译过程可以用下图表示:

flowchart LR
    subgraph 源代码
        A[main.c]
    end

    subgraph 汇编代码
        C[main.s]
    end

    A --编译 -S--> C

    subgraph 机器码
        D[main.o]
    end

    C --汇编 -c--> D

    机器码 ---> 可执行程序
    可执行程序 --> z([运行])

编译原理中的“编译”二字与此处的“编译”二字并不是一个意思,此处的编译是具体的过程,从源代码到最终的可执行程序,而编译原理中的“编译”更加广泛,一切与解析某一种语言并转化为其他“语言”有关的过程都离不开此原理。

比如 python 的解释器(解释 python 代码并转化为具体指令运行),Markdown的解析渲染(解析 Markdown 并转化为 HTML 进行渲染),以及 SQL 的解析执行(解析 SQL 语句为具体的操作并执行)等等。

而这些过程都可以大致抽象为两大部分:

  • 前端部分(Frontend)

负责将源代码经过一步步分析转化为一个抽象的树形结构 —— 抽象语法树(AST)

  • 后端部分(Backend)

可能是个代码生成器,依照抽象的树形结构生成具体实际的转化目标的指令或语言等

或许还会包含优化器等部分

编译原理 1. 词法分析 - flex

一、概述

flex 手册:Lexical Analysis With Flex, for Flex 2.6.2: Top (westes.github.io)

flex 是一个用于生成基于 C/C++ 的词法分析器的程序。

它的输入是一个 .flex 文件,其中包含着一对对由 正则表达式C 语言代码 组成的 规则

它的输出是一个 C 语言源文件,其中会包含一个 yylex() 函数,该函数会对输入的字符序列进行扫描,根据 规则 中的一个个 正则表达式 进行匹配并执行其对应的 C 语言代码

配置 paddlepaddle-gpu

Windows 下的 PIP 安装-使用文档-PaddlePaddle深度学习平台

Windows 下的 Conda 安装-使用文档-PaddlePaddle深度学习平台

目前 paddlepaddle-gpu 只支持到 python3.10,如果使用 python3.11,pip 会无法匹配到包。

此处(附录-使用文档-PaddlePaddle深度学习平台)有GPU 及其对应架构和推荐 CUDA 版本的列表,按照对应版本安装对应的 paddlepaddle-gpu。

比如我笔记本的 GTX1660Ti 是 Turing 架构,可以使用 CUDA10 和 CUDA11,不过 paddlepaddle 推荐对于安培以前的架构使用 CUDA10.2,性能会更优,因此选择

「CUDA 工具包 10.2 配合 cuDNN v7.6.5」

首先安装对应的 paddlepaddle-gpu包:

image-20230616123330993

Text Only
python -m pip install paddlepaddle-gpu==2.4.2 -i https://pypi.tuna.tsinghua.edu.cn/simple

然后安装 CUDA 和 cuDNN

CUDA Installation Guide for Microsoft Windows (nvidia.com)

CUDA Toolkit 12.1 Update 1 Downloads | NVIDIA Developer

这个网站下方 Archive of Previous CUDA Release 中有以前的版本

Installation Guide - NVIDIA Docs

cuDNN Download | NVIDIA Developer

一切同理

跟着文档走,下载 Zlib 配置环境变量添加 zlibwapi.dll 所在路径到 PATH

然后下载 cuDNN 解压并复制内容到 CUDA 安装路径下。

然后理论上就OK了

大数据华为云实践作业踩坑记录(实验报告

略去华为云资源准备。

修正 JDK 安装部分文档

官方文档中安装 JDK 部分有误,修改部分已在下面代码块中以 diff 格式展示(绿色部分)

其实正文中有设置 PATH 添加 $JAVA_HOME/bin,但是这文档说实话组织的真是一言难尽,代码块也不用等宽字体(

  1. 安装 OpenJDK 执行如下命令,将 jdk 安装包拷贝到安装目录下:
Diff
1
2
3
4
cd /root
wget https://bigdata-tools-hw.obs.cn-north-1.myhuaweicloud.com/OpenJDK8U-jdk_aarch64_linux_hotspot_8u191b12.tar.gz
+ mkdir /usr/lib/jvm
cp OpenJDK8U-jdk_aarch64_linux_hotspot_8u191b12.tar.gz /usr/lib/jvm/
  1. 步骤 2

进入安装目录解压安装包:

Bash
cd /usr/lib/jvm/
tar zxvf OpenJDK8U-jdk_aarch64_linux_hotspot_8u191b12.tar.gz
  1. 步骤 3

在/etc/profile 增加如下的配置:

Diff
export JAVA_HOME=/usr/lib/jvm/jdk8u191-b12
+ export PATH=$PATH:$JAVA_HOME/bin
  1. 步骤 4

执行 source 命令使环境变量生效:

Bash
source /etc/profile
  1. 步骤 5

查看 java 安装版本:

Bash
java -version

输出:

Text Only
1
2
3
[root@ecs-bigdatapro ~]# java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_191-b12)

搭建 Hadoop 伪分布式集群

1. Hadoop 安装

创建以下两个目录:

  • /home/modules 作为 hadoop 的安装目录
  • /home/nm/localdir 作为 NodeManager 的数据目录
Bash
mkdir -p /home/modules
mkdir -p /home/nm/localdir

然后下载 hadoop 并解压到 /home/modules

Bash
1
2
3
cd /root
wget https://bigdata-tools-hw.obs.cn-north-1.myhuaweicloud.com/hadoop-2.8.3.tar.gz
tar -zxvf hadoop-2.8.3.tar.gz -C /home/modules

编辑 /etc/profile 添加以下内容:

Text Only
1
2
3
export HADOOP_HOME=/home/modules/hadoop-2.8.3
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
export HADOOP_CLASSPATH=/home/modules/hadoop-2.8.3/share/hadoop/tools/lib/*:$HADOOP_CLASSPATH

重新加载 profile 使更改生效:

Bash
source /etc/profile

2. 伪分布式配置

编辑 /home/modules/hadoop-2.8.3/etc/hadoop/core-site.xml,在 configuration 标签之间添加以下内容:

Text Only
1
2
3
4
5
6
7
8
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://ecs-bigdatapro:8020</value>
</property>
<property>
    <name>hadoop.tmp.dir</name>
    <value>/home/modules/hadoop-2.8.3/tmp</value>
</property>

编辑 /home/modules/hadoop-2.8.3/etc/hadoop/hdfs-site.xml,在 configuration 标签之间添加以下内容:

Text Only
<property>
    <name>dfs.replication</name>
    <value>1</value>
</property>
<property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>ecs-bigdatapro:50090</value>
</property>
<property>
    <name>dfs.namenode.secondary.https-address</name>
    <value>ecs-bigdatapro:50091</value>
</property>

编辑 /home/modules/hadoop-2.8.3/etc/hadoop/yarn-site.xml,在 configuration 标签之间添加以下内容:

Text Only
<property>
    <name>yarn.nodemanager.local-dirs</name>
    <value>/home/nm/localdir</value>
</property>
<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname</name>
    <value>ecs-bigdatapro</value>
</property>
<property>
    <name>yarn.resourcemanager.scheduler.class</name>
    <value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler</value>
</property>
<property>
    <name>yarn.log-aggregation-enable</name>
    <value>true</value>
</property>
<property>
    <name>yarn.log.server.url</name>
    <value>http://ecs-bigdatapro:19888/jobhistory/logs</value>
</property>

编辑 /home/modules/hadoop-2.8.3/etc/hadoop/mapred-site.xml,在 configuration 标签之间添加以下内容:

这一步如果不存在 mapred-site.xml 可以先将 mapred-site.xml.template 复制一份为 mapred-site.xml

Bash
cp /home/modules/hadoop-2.8.3/etc/hadoop/mapred-site.xml.template /home/modules/hadoop-2.8.3/etc/hadoop/mapred-site.xml
Text Only
<property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
</property>
<property>
    <name>mapreduce.jobhistory.address</name>
    <value>ecs-bigdatapro:10020</value>
</property>
<property>
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>ecs-bigdatapro:19888</value>
</property>
<property>
    <name>mapred.task.timeout</name>
    <value>1800000</value>
</property>

配置 slaves,编辑 /home/modules/hadoop-2.8.3/etc/hadoop/slaves 内容为主机名:

Text Only
ecs-bigdatapro

编辑 /home/modules/hadoop-2.8.3/etc/hadoop/hadoop-env.sh,修改其中的 JAVA_HOME 为安装 JDK 时设置的 JAVA_HOME。

初始化名节点:

Bash
hdfs namenode -format

这一步可能会报错 lineNumber: 1; columnNumber: 20; XML version "2.0" is not supported, only XML 1.0 is supported.

把上面几个配置文件开头的 <?xml version="2.0" encoding="UTF-8"?> 中的 2.0 改成 1.0 即可。(说实话,这文档。。。

image-20230622194315494

启动 HDFS:

Bash
start-dfs.sh

使用 jps 查看启动的进程:

image-20230622194729551

测试 HDFS 命令:

Bash
hdfs dfs -mkdir /bigdata
hdfs dfs -ls /

image-20230622195045715

3. 与 OBS 互联

在 OBS 上上传了一份正在写的实验报告

image-20230622195151764

建立 OBS 缓存目录:

Bash
mkdir -p /home/modules/data/buf

编辑 /home/modules/hadoop-2.8.3/etc/hadoop/core-site.xml,在 configuration 标签中继续添加以下内容:

Text Only
<property>
    <name>fs.obs.readahead.inputstream.enabled</name>
    <value>true</value>
</property>
<property>
    <name>fs.obs.access.key</name>
    <value>华为云 AK</value>
</property>
<property>
    <name>fs.obs.secret.key</name>
    <value>华为云 SK</value>
</property>
<property>
    <name>fs.obs.endpoint</name>
    <value>OBS 的 endpoint</value>
</property>
<property>
    <name>fs.obs.buffer.dir</name>
    <value>/home/modules/data/buf</value>
</property>
<property>
    <name>fs.obs.impl</name>
    <value>org.apache.hadoop.fs.obs.OBSFileSystem</value>
</property>
<property>
    <name>fs.obs.connection.ssl.enabled</name>
    <value>false</value>
</property>
<property>
    <name>fs.obs.fast.upload</name>
    <value>true</value>
</property>

添加 jar 包:

Bash
1
2
3
4
5
6
cd /root
wget https://bigdata-tools-hw.obs.cn-north-1.myhuaweicloud.com/hadoop-huaweicloud-2.8.3-hw-39.jar
cp hadoop-huaweicloud-2.8.3-hw-39.jar /home/modules/hadoop-2.8.3/share/hadoop/common/lib/
cp hadoop-huaweicloud-2.8.3-hw-39.jar /home/modules/hadoop-2.8.3/share/hadoop/tools/lib
cp hadoop-huaweicloud-2.8.3-hw-39.jar /home/modules/hadoop-2.8.3/share/hadoop/httpfs/tomcat/webapps/webhdfs/WEB-INF/lib/
cp hadoop-huaweicloud-2.8.3-hw-39.jar /home/modules/hadoop-2.8.3/share/hadoop/hdfs/lib/

测试(查看 OBS 文件):

Bash
hdfs dfs -ls obs://obs-bigdatapro-azurice/

这里又是两个坑,

一个是要先 start-dfs.shstart-dfs.sh 重启 HDFS 使配置文件生效

一个是访问的 obs URL 中要与创建 OBS 中填写的名称相同。

image-20230622200652447

搭建 Spark 集群

1. Spark 安装配置

安装:

Bash
1
2
3
4
5
6
cd /root
wget https://bigdata-tools-hw.obs.cn-north-1.myhuaweicloud.com/spark-2.3.0-bin-without-hadoop.tgz
tar -zxvf spark-2.3.0-bin-without-hadoop.tgz
mv spark-2.3.0-bin-without-hadoop/ /home/modules/spark-2.3.0
cp /root/hadoop-huaweicloud-2.8.3-hw-39.jar /home/modules/spark-2.3.0/jars/
cp /home/modules/hadoop-2.8.3/share/hadoop/common/lib/snappy-java-1.0.4.1.jar /home/modules/spark-2.3.0/jars/

配置:

Bash
cd /home/modules/spark-2.3.0/conf/
cp spark-env.sh.template spark-env.sh

编辑 spark-env.sh,在末尾添加以下内容:

Text Only
1
2
3
4
5
6
export JAVA_HOME=/usr/lib/jvm/jdk8u191-b12
export SCALA_HOME=/home/modules/spark-2.3.0/examples/src/main/scala
export HADOOP_HOME=/home/modules/hadoop-2.8.3
export HADOOP_CONF_DIR=/home/modules/hadoop-2.8.3/etc/hadoop
export SPARK_HOME=/home/modules/spark-2.3.0
export SPARK_DIST_CLASSPATH=$(/home/modules/hadoop-2.8.3/bin/hadoop classpath)

编辑 /etc/profile,添加 spark 环境变量:

Text Only
export SPARK_HOME=/home/modules/spark-2.3.0
export PATH=${SPARK_HOME}/bin:${SPARK_HOME}/sbin:$PATH

重新加载 /etc/profile 使更改生效:

Text Only
source /etc/profile

使用 spark-shell 进入 spark shell:

image-20230622201857886

2. 验证存算分离

向 OBS 上再传一份 playerinfo.txt,内容如下:

Text Only
1
2
3
4
5
Alex James Lax Genu
Kerry Mary Olivia William
Hale Edith Vera Robert
Mary Olivia James Lax
Edith Vera Robertm Genu

(然后把我之前传的实验报告删了

启动 pyspark:

Text Only
pyspark

测试用 python 语句以及结果如下所示:

Python
1
2
3
4
5
lines = spark.read.text("obs://obs-bigdatapro-azurice/").rdd.map(lambda r: r[0])
counts = lines.flatMap(lambda x: x.split(' ')).map(lambda x: (x, 1)).reduceByKey(lambda x, y: x + y)
output = counts.collect()
for (word, count) in output:
    print("%s: %i" % (word, count))

image-20230622202604353