使用Git Hooks实现开发部署任务自动化

git hooks - git push后触发 通过git hooks post-update函数实现push后触发业务逻辑操作 阅读详情

使用Git Hooks实现开发部署任务自动化

提供:ZStack社区

前言

版本控制,这是现代软件开发的核心需求之一。有了它,软件项目可以安全的跟踪代码变更并执行回溯、完整性检查、协同开发等多种操作。在各种版本控制软件中,git是近年来最流行的软件之一,它的去中心化架构以及源码变更交换的速度被很多开发者青睐。

在git的众多优点中,最有用的一点莫过于它的灵活性。通过“hooks”(钩子)系统,开发者和管理员们可以指定git在不同事件、不同动作下执行特定的脚本。

本文将介绍git hooks的基本思路以及用法,示范如何在你的环境中实现自动化的任务。本文所用的操作系统是Ubuntu 14.04服务器版,理论上任何可以跑git的系统都可以用同样的方法来做。

前提条件

首先你的服务器上先要安装过git。Ubuntu 14.04的用户可以查看这篇教程了解如何在Ubuntu 14.04上安装git。

其次你应该能够进行基本的git操作。如果你觉得对git不太熟,可以先看看这个Git入门教程。

上述条件达成后,请继续往下阅读。

Git Hooks的基本思路

Git hooks的概念相当简单,它是为了一个单一需求而被设计实现的。在一个共享项目(或者说多人协同开发的项目)的开发过程中,团队成员需要确保其编码风格的统一,确保部署方式的统一,等等(git的用户经常会涉及到此类场景),而这些工作会造成大量的重复劳动。

Git hooks是基于事件的(event-based)。当你执行特定的git指令时,该软件会从git仓库下的hooks目录下检查是否有相对应的脚本,如果有则执行之。

有些脚本是在动作执行之前被执行的,这种“先行脚本”可用于实现代码规范的统一、完整性检查、环境搭建等功能。有些脚本则在事件之后被执行,这种“后行脚本”可用于实现代码的部署、权限错误纠正(git在这方面的功能有点欠缺)等功能。

总体来说,git hooks可以实现策略强制执行、确保一致性、环境控制、部署任务处理等多种功能。

Scott Chacon在他的Pro Git一书中将hooks划分为如下类型:

  • 客户端的hook:此类hook在提交者(committer)的计算机上被调用执行。此类hook又分为如下几类:

    • 代码提交相关的工作流hook:提交类hook作用在代码提交的动作前后,通常用于运行完整性检查、提交信息生成、信息内容验证等功能,也可以用来发送通知。
    • Email相关工作流hook:Email类hook主要用于使用Email提交的代码补丁。像是Linux内核这样的项目是采用Email进行补丁提交的,就可以使用此类hook。工作方式和提交类hook类似,而且项目维护者可以用此类hook直接完成打补丁的动作。
    • 其他类:包括代码合并、签出(check out)、rebase、重写(rewrite)、以及软件仓库的清理等工作。
  • 服务器端hook:此类hook作用在服务器端,一般用于接收推送,部署在项目的git仓库主干(main)所在的服务器上。Chacon将服务器端hook分为两类:

    • 接受触发类:在服务器接收到一个推送之前或之后执行动作,前触发常用于检查,后触发常用于部署。
    • 更新:类似于前触发,不过更新类hook是以分支(branch)作为作用对象,在每一个分支更新通过之前执行代码。

上述分类有助于我们对hook建立一个整体的概念,了解它可以用于哪类事件。当然了,要能够实际的运用它,还需要亲自动手操作、调试。

有些hook可以接受参数。也就是说,当git调用了hook的脚本时,我们可以传递一些数据给这个脚本。可用的hook列表如下:

Hook名称触发指令描述参数的个数与描述
applypatch-msg`git am`可以编辑commit时提交的message。通常用于验证或纠正补丁提交的信息以符合项目标准。(1) 包含预备commit信息的文件名
pre-applypatch`git am`虽然这个hook的名称是“打补丁前”,不过实际上的调用时机是打补丁之后、变更commit之前。如果以非0的状态退出,会导致变更成为uncommitted状态。可用于在实际进行commit之前检查代码树的状态。 无
post-applypatch`git am`本hook的调用时机是打补丁后、commit完成提交后。因此,本hook无法用于取消进程,而主要用于通知。 无
pre-commit`git commit`本hook的调用时机是在获取commit message之前。如果以非0的状态退出则会取消本次commit。主要用于检查commit本身(而不是message) 无
prepare-commit-msg`git commit`本hook的调用时机是在接收默认commit message之后、启动commit message编辑器之前。非0的返回结果会取消本次commit。本hook可用于强制应用指定的commit message。 1. 包含commit message的文件名。2. commit message的源(message、template、merge、squash或commit)。3. commit的SHA-1(在现有commit上操作的情况)。
commit-msg`git commit`可用于在message提交之后修改message的内容或打回message不合格的commit。非0的返回结果会取消本次commit。 (1) 包含message内容的文件名。
post-commit`git commit`本hook在commit完成之后调用,因此无法用于打回commit。主要用于通知。 无
pre-rebase`git rebase`在执行rebase的时候调用,可用于中断不想要的rebase。 1. 本次fork的上游。2. 被rebase的分支(如果rebase的是当前分支则没有此参数)
post-checkout`git checkout` 和 `git clone`更新工作树后调用checkout时调用,或者执行 git clone后调用。主要用于验证环境、显示变更、配置环境。 1. 之前的HEAD的ref。 2. 新HEAD的ref。 3. 一个标签,表示其是一次branch checkout还是file checkout。
post-merge`git merge` 或 `git pull`合并后调用,无法用于取消合并。可用于进行权限操作等git无法执行的动作。 (1) 一个标签,表示是否是一次标注为squash的merge。
pre-push`git push`在往远程push之前调用。本hook除了携带参数之外,还同时给stdin输入了如下信息:” ”(每项之间有空格)。这些信息可以用来做一些检查,比如说,如果本地(local)sha1为40个零,则本次push是一个删除操作;如果远程(remote)sha1是40个零,则是一个新的分支。非0的返回结果会取消本次push。 1. 远程目标的名称。 2. 远程目标的位置。
pre-receive远程repo进行`git-receive-pack`本hook在远程repo更新刚被push的ref之前调用。非0的返回结果会中断本次进程。本hook虽然不携带参数,但是会给stdin输入如下信息:” ”。 无
update远程repo进行`git-receive-pack`本hook在远程repo每一次ref被push的时候调用(而不是每一次push)。可以用于满足“所有的commit只能快进”这样的需求。 1. 被更新的ref名称。2. 老的对象名称。3. 新的对象名称。
post-receive远程repo进行`git-receive-pack`本hook在远程repo上所有ref被更新后,push操作的时候调用。本hook不携带参数,但可以从stdin接收信息,接收格式为” ”。因为hook的调用在更新之后进行,因此无法用于终止进程。无
post-update远程repo进行`git-receive-pack`本hook仅在所有的ref被push之后执行一次。它与post-receive很像,但是不接收旧值与新值。主要用于通知。 每个被push的repo都会生成一个参数,参数内容是ref的名称
pre-auto-gc`git gc –auto`用于在自动清理repo之前做一些检查。无
post-rewrite`git commit –amend`,`git-rebase`本hook在git命令重写(rewrite)已经被commit的数据时调用。除了其携带的参数之外,本hook还从stdin接收信息,信息格式为” ”。 触发本hook的命令名称(amend或者rebase)

下面我们通过几个场景来说明git hook的使用方法。

设置软件仓库

首先,在用户目录下创建一个新的空仓库,命名为 proj。

mkdir ~/proj
cd ~/proj
git init


Initialized empty Git repository in /home/demo/proj/.git/

我们现在已经处于这个git控制的目录下,目录下还没有任何内容。在添加任何内容之前,我们先进入 .git 这个隐藏目录下:

cd .git
ls -F


branches/  config  description  HEAD  hooks/  info/  objects/  refs/

这里可以看到一些文件和目录。我们感兴趣的是 hooks 这个目录:

cd hooks
ls -l


total 40
-rwxrwxr-x 1 demo demo  452 Aug  8 16:50 applypatch-msg.sample
-rwxrwxr-x 1 demo demo  896 Aug  8 16:50 commit-msg.sample
-rwxrwxr-x 1 demo demo  189 Aug  8 16:50 post-update.sample
-rwxrwxr-x 1 demo demo  398 Aug  8 16:50 pre-applypatch.sample
-rwxrwxr-x 1 demo demo 1642 Aug  8 16:50 pre-commit.sample
-rwxrwxr-x 1 demo demo 1239 Aug  8 16:50 prepare-commit-msg.sample
-rwxrwxr-x 1 demo demo 1352 Aug  8 16:50 pre-push.sample
-rwxrwxr-x 1 demo demo 4898 Aug  8 16:50 pre-rebase.sample
-rwxrwxr-x 1 demo demo 3611 Aug  8 16:50 update.sample

这里面已经有了一些东西。首先可以看到的是,目录下的每一个文件都被标记为“可执行”。脚本通过文件名被调用,因此它们必须是可执行的,而且其内容的第一行必须有一个Shebang魔术数字(#!)引用至正确的脚本解析器。常用的脚本语言有bash、perl、python等。

其次,我们可以看到现在所有的文件都有一个 .sample 后缀名。Git决定是否执行一个hook文件完全是通过其文件名来判定的, .sample 代表不执行,所以如果要激活某个hook,则需要将这个后缀名删除。

现在,回到项目的根目录:

cd ../..

示范1:用“提交后触发”类hook在本地Web服务器上部署代码

第一个示范将用到 post-commit hook 来自动给本地Web服务器提交代码。我们会让git在每次commit提交后都做一次部署——这当然不适用于生产环境,但你明白这个意思就行。

首先安装一个Apache:

sudo apt-get update
sudo apt-get install apache2

我们的脚本需要能够修改 /var/www/html 路径(Web服务器根目录)下的内容,因此需要添加写权限。我们可以直接将当前系统用户设置为该目录的owner:

sudo chown -R `whoami`:`id -gn` /var/www/html

接下来,回到我们的项目目录,创建一个 index.html 文件:

cd ~/proj
nano index.html

里面随便写点什么内容:

<h1>Here is a title!</h1>

<p>Please deploy me!</p>

保存退出,然后告诉git跟踪这个文件:

git add .

现在,我们就要开始给这个仓库设置 post-commit hook了。在 .git/hooks 目录下创建这个文件:

vim .git/hooks/post-commit

在编写这个文件之前,我们先来了解一下git在运行hook的时候是如何设置环境的。

有关Git hooks的环境变量

调用hook的时候会涉及一些环境变量。要让我们的脚本完成工作,我们需要把git在调用 post-commit hook 时变更的环境变量再改回去。

这是编写git hook时需要特别注意的一点。Git在调用不同hook的时候会设置不同的环境变量。也就是说,不同的hook会导致git从不同的环境拉取信息。

这样一来,你的脚本环境会变得不可控,你可能根本没意识到哪些变量被自动更改了。糟糕的是,这些变更的变量完全没有在git的文档中说明。

幸运的是,Mark Longair找到了一种测试方法来检查每个hook被调用时所变更的环境变量。这个测试方法只需要你把下面这几行代码粘贴到你的git hook脚本中即可:

#!/bin/bash
echo Running $BASH_SOURCE
set | egrep GIT
echo PWD is $PWD

他这篇文章是在2011年写的,当时的git版本在1.7.1。我写这篇文章的时间是2014年8月,用的git版本是1.9.1,操作系统是Ubuntu 14.04,应该说还是有一些变化。总之,下面是我的测试结果:

在以下测试中,本地项目目录为 /home/demo/test_hooks,远程路径为 /home/demo/origin/test_hooks.git。

  • Hooks:applypatch-msg、pre-applypatch、post-applypatch

    • 环境变量:
    • GIT_AUTHOR_DATE=’Mon, 11 Aug 2014 11:25:16 -0400’

    • GIT_AUTHOR_EMAIL=demo@example.com

    • GIT_AUTHOR_NAME=’Demo User’

    • GIT_INTERNAL_GETTEXT_SH_SCHEME=gnu

    • GIT_REFLOG_ACTION=am

    • 工作目录: /home/demo/test_hooks

  • Hooks:pre-commit、prepare-commit-msg、commit-msg、post-commit

    • 环境变量:
    • GIT_AUTHOR_DATE=’@1407774159 -0400’

    • GIT_AUTHOR_EMAIL=demo@example.com

    • GIT_AUTHOR_NAME=’Demo User’

    • GIT_DIR=.git

    • GIT_EDITOR=:

    • GIT_INDEX_FILE=.git/index

    • GIT_PREFIX=

    • 工作目录: /home/demo/test_hooks

  • Hooks: pre-rebase

    • 环境变量:
    • GIT_INTERNAL_GETTEXT_SH_SCHEME=gnu

    • GIT_REFLOG_ACTION=rebase

    • 工作目录: /home/demo/test_hooks

  • Hooks: post-checkout

    • 环境变量:
    • GIT_DIR=.git

    • GIT_PREFIX=

    • 工作目录: /home/demo/test_hooks

  • Hooks: post-merge

    • 环境变量:
    • GITHEAD_4b407c…

    • GIT_DIR=.git

    • GIT_INTERNAL_GETTEXT_SH_SCHEME=gnu

    • GIT_PREFIX=

    • GIT_REFLOG_ACTION=’pull other master’

    • 工作目录: /home/demo/test_hooks

  • Hooks: pre-push

    • 环境变量:
    • GIT_PREFIX=

    • 工作目录: /home/demo/test_hooks

  • Hooks: pre-receive, update, post-receive, post-update

    • 环境变量:
    • GIT_DIR=.

    • 工作目录: /home/demo/origin/test_hooks.git

  • Hooks: pre-auto-gc

    • 这个很难测试所以信息缺失
  • Hooks: post-rewrite

    • 环境变量:
    • GIT_AUTHOR_DATE=’@1407773551 -0400’

    • GIT_AUTHOR_EMAIL=demo@example.com

    • GIT_AUTHOR_NAME=’Demo User’

    • GIT_DIR=.git

    • GIT_PREFIX=

    • 工作目录: /home/demo/test_hooks

以上就是git在调用不同hook时所看到的环境。有了这些信息,我们可以回去继续编写我们的脚本了。

继续回来写脚本

我们现在知道了 post-commit hook 会改变的环境变量。把这个信息记录下来。

Git hooks是标准的脚本,所以要在第一行告诉git用什么解释器:

#!/bin/bash

然后,我们要让git把最新版本的代码仓库(最新一次提交后)解包到Web服务器的根目录下。这需要把工作目录设置为Apache的文件根目录,把git目录设置为软件仓库的目录。

同时,我们还需要确保这个过程每次都能成功,即使出现了冲突也要强制执行。接下来的脚本是这样写的:

#!/bin/bash
git --work-tree=/var/www/html --git-dir=/home/demo/proj/.git checkout -f

At this point, we are almost done. However, we need to look extra close at the environmental variables that are set each time the post-commit hook is called. In particular, the GIT_INDEX_FILE is set to.git/index.

这样就基本完成了。接下来的工作就是有关环境变量的工作了。post-commit hook被调用时所变更的环境变量中,有一个 GIT_INDEX_FILE 被变更为 .git/index,这个是我们关注的重点。

这个路径是相对于工作路径的,而我们现在的工作路径是 /var/www/html,而这下面是没有 .git/index 目录的,导致脚本出错。所以,我们需要手动的把这个变量改回正确的路径。这个unset指令需要放在checkout指令之前,像这样:

#!/bin/bash
unset GIT_INDEX_FILE
git --work-tree=/var/www/html --git-dir=/home/demo/proj/.git checkout -f

很多时候,这种问题是很难跟踪到的。如果你在使用git hook之前没意识到环境变量的问题,往往会到处踩坑。

总之,我们的脚本完成了,现在保存退出。

然后,我们需要给这个脚本文件添加执行权限:

chmod +x .git/hooks/post-commit

现在回到项目所在的目录,来一发commit试试~

cd ~/proj
git commit -m "here we go..."

现在到浏览器里看看效果,是不是我们刚才写的 index.html 的内容:

http://你的服务器IP

Test index.html

正如我们所看到的,刚才提交的代码已经自动部署到Web服务器的文件根目录下啦。再来更新点内容试试:

echo "<p>Here is a change.</p>" >> index.html
git add .
git commit -m "First change"

刷新浏览器页面,看看变更生效没:

deploy changes

你看,这让本地测试变得方便了很多。当然正如我们前面说的,生产环境上是不能这么用的。要上生产环境的代码一定要仔细的测试验证过才行。

使用Git hook往另一台生产服务器上部署

下面我将示范往生产环境服务器上部署代码的正确姿势。我将使用push-to-deploy模型,在我们往一个裸git仓库(bare git repo)推送代码的时候触发线上web服务器的代码更新。

我们刚才的那台机器现在就当作开发机,我们每次commit之后这里都会自动部署,可随时查看变更效果。

接下来,我会设置另一台服务器做我们的生产服务器。这台服务器上有一个裸仓库用于接收推送,还有一个能够被推送行为触发的git hook。然后,以普通用户在sudo权限下执行如下步骤。

设置生产服务器的post-receive hook

首先,在生产服务器上安装Web服务器:

sudo apt-get update
sudo apt-get install apache2

别忘了给git设置权限:

sudo chown -R `whoami`:`id -gn` /var/www/html

也别忘了安装git:

sudo apt-get install git

然后,还是在用户主目录下创建同样名称的项目目录。然后,在这个目录下初始化一个裸仓库。裸仓库是没有工作路径的,它比较适合不经常直接操作的服务器。

mkdir ~/proj
cd ~/proj
git init --bare

因为这是裸仓库,所以它没有工作路径,而一个正常git仓库的 .git 路径下的所有文件都会直接出现在这个裸仓库的根目录下。

现在,创建我们的 post-receive hook,这个hook在服务器收到 git push 时被触发。用编辑器打开这个文件:

nano hooks/post-receive

第一行还是要定义我们的脚本类型。然后,告诉git我们想做什么,还是跟之前的 post-commit 做的事情一样,把文件解包到这台Web服务器的文件根目录下:

#!/bin/bash
git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f

因为是裸仓库,所以 --git-dir 需要指定一个绝对路径。其他的都差不多。

然后,我们需要添加一些额外的逻辑,因为我们不希望把标记为 test-feature 的分支代码部署到生产服务器。我们的生产服务器仅仅部署 master 分支的内容。

在之前的那张表格中可以看到, post-receive hook能够从git接受三个通过标准输入(standard input)写到脚本中的内容,包括上一版的commit hash(),最新版的commit hash(),以及引用名称。我们可以用这些信息检查ref是否是master分支。

首先我们需要从标准输入读取内容。每一个ref被推送时,上述三条信息都会以标准输入的格式被提供给脚本,三条信息之间由空格分隔。我们可以在一个 while 循环中读取这些信息,把上面的git命令放进这个循环中:

#!/bin/bash
while read oldrev newrev ref
do
    git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f
done

然后我们需要添加一个判定条件。一个来自master分支的push,其ref通常会包含一个 refs/heads/master 字段。这可以作为我们判定的依据:

#!/bin/bash
while read oldrev newrev ref
do
    if [[ $ref =~ .*/master$ ]];
    then
        git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f
    fi
done

另一方面,服务器端的hook可以让git传递一些消息返回给客户端。发送到标准输出的内容都会被转发给客户端,我们可以用这个功能给用户发送通知。

这个通知应该包含一些场景描述以及系统最终执行了什么动作。对于来自非master的推送,我们也应该给用户返回信息,告诉他们为什么这次推送是成功的但代码并没有部署到线上:

#!/bin/bash
while read oldrev newrev ref
do
    if [[ $ref =~ .*/master$ ]];
    then
        echo "Master ref received.  Deploying master branch to production..."
        git --work-tree=/var/www/html --git-dir=/home/demo/proj checkout -f
    else
        echo "Ref $ref successfully received.  Doing nothing: only the master branch may be deployed on this server."
    fi
done

编辑完毕后,保存退出。

最后,别忘了把脚本文件设置为可执行:

chmod +x hooks/post-receive

现在,我们就可以在我们的客户端访问这个远程服务器了。

在客户端上配置远程服务器

现在回到我们的客户端,也就是开发机上,进入项目目录:

cd ~/proj

我们要在这个目录下将我们的远程服务器添加进来,就叫做 production。你需要知道远程服务器上的用户名、服务器的IP或者域名、以及裸仓库相对于用户home目录的路径。整个操作指令看起来差不多是这样的:

git remote add production demo@server_domain_or_IP:proj

来push一个看看:

git push production master

如果你的SSH密钥还没设置,则需要敲入你的密码。服务器返回的内容看起来应该是这样的:

Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 473 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
remote: Master ref received.  Deploying master branch...
To demo@107.170.14.32:proj
   009183f..f1b9027  master -> master

我们在这里能够看到刚才在post-receive hook里面写的信息了。如果我们从浏览器里访问远程服务器的IP或者域名,则应该能看到最新版的页面:

pushed production

看起来,这个hook已经成功的把我们的代码部署到生产环境啦。

现在继续来测试。我们在开发机上创建一个新的分支test_feature,签入到这个分支下面:

git checkout -b test_feature

现在,我们所做的变更都会在 test_feature 这个测试分支中进行。来改点东西先:

echo "<h2>New Feature Here</h2>" >> index.html
git add .
git commit -m "Trying out new feature"

这样commit之后,在浏览器里输入开发机的IP,你应该能看到这个变更:

commit changes

正如我们所需要的那样,开发机上的Web服务器内容更新了。这样进行本地测试再方便不过。

然后,试试把这个 test_feature 推送到远程服务器上:

git push production test_feature

从post-receive hook返回的结果应该是这样的:

Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 301 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Ref refs/heads/test_feature successfully received.  Doing nothing: only the master branch may be deployed on this server
To demo@107.170.14.32:proj
   83e9dc4..5617b50  test_feature -> test_feature

在浏览器里输入生产服务器的IP地址,应该是啥变化都没有。这正是我们需要的,因为我们的变更没有提交到master。

现在,如果我们完成了测试,想把这个变更推送到生产服务器上,我们可以这样做。首先,签入到master分支,把刚才的test_feature分支合并进来:

git checkout master
git merge test_feature

合并完成后,再推送到生产服务器:

git push production master

现在再到浏览器里输入生产服务器的IP看看,变更被成功部署了:

Pushed to production

这样的工作流,在开发机上实现了实时部署,在生产环境上实现了推送master就部署,皆大欢喜。

总结

至此,你对于git hooks的用法应该有了一个大致的了解,对如何使用它来实现你的任务自动化有了概念。它可以用于部署代码,可以用于维护代码质量,拒绝任何不符合要求的变更。

虽然git hooks很好用,但实际运用往往不容易掌握,遇到问题后的排障过程也很烦人。要编写出高效的hook,需要长期的练习,把各种配置、参数、标准输入、环境变量都玩清楚。这会花费相当长的时间,但这些投入最终会帮助你和你的团队免除大量的手动操作,带来更高的回报。

本文来源自DigitalOcean Community。英文原文:How To Use Git Hooks To Automate Development and Deployment Tasks by Justin Ellingwood

翻译:lazycai

利用Git Hooks实现代码提交后的自动化部署 本文详细介绍了如何利用Git Hooks,特别是post-update钩子,实现代码提交后的自动化部署。通过配置服务器端钩子与SSH免密登录,开发者可在执行git push后自动将代码同步至部署服务器,从而将重复的手动操作转化为高效、可靠的自动化流程,极大提升开发与运维效率。 阅读详情

相关推荐

如何使用 Git Hooks 进行提交自动化

Git 挂钩是在 Git 命令之前或之后运行的 bash 脚本,例如提交和推送。它们允许您自动执行存储库中的重复操作,并将过滤器和检查应用于您的 Git 工作流程。 什么是 Git 钩子? Git 挂钩实际上只是.git/hooks/ 文件夹中具有特殊名称的 bash 脚本。Git 将在执行某些任务时自动调用这些函数,允许您“挂钩”到 Git 工作流中,以使用自己的代码对其进行修改。 Git 存储库使用一些示例进行初始化;应用它们所需要做的就是取消注释扩展。这意味着每个钩子只能有一个脚本,所以如果你想做多.

学海无涯苦作舟的博客 771

【项目部署】Githooks结合shell脚本实现自动化部署

Githooks实现自动化部署

destiny_balabala的博客 1764

别再纠结了!实测罗技Flow、对拷线、微软Mouse without Borders,我的最终选择是...

本文通过实测对比罗技Flow、对拷线和微软Mouse without Borders等多设备控制方案,详细分析了各自的优缺点及适用场景。作者最终选择了对拷线与罗技键鼠的组合方案,为专业用户提供了稳定可靠的多设备协同办公解决方案,特别适合需要频繁传输大文件和跨设备操作的用户。

weixin_33696106的博客 408

基于GitHooks实现项目自动实时部署

基于GitHooks实现项目自动实时部署

共产主义接班人 1128

fNIRS 公开数据集整理

关注“心仪脑”查看更多脑科学知识的分享。 关键词:数据整理、fNIRS 之前我们向大家推送了 Public Neuroscience Dataset 系列主题的第一期:《EEG公开数据集》,我们同时意识到大家对于神经科学公开数据集的需求。本期是该系列主题的第二期,我们在延续第一期初衷的基础上,整理了功能性近红外光谱(fNIRS)技术的公开数据集。 fNIRS 是一种非侵入性、便携且价格低廉的光学神经成像技术,它具有可观的空间和时间分辨率。因fNIRS技术问世较EEG晚了许多,所以应用此技术开展研究发.

psybrain的博客 4272

脑机接口最新发展动态报告 (2024-2025)

脑机接口动态

高山 4108

利用gitHook实现自动部署

gitHook 当进行开发的环境在本地,而运行的环境要在服务端时,每一次提交代码都需要在服务端pull一次。而利用git的hooks功能,能够让我们省去这一步,下面我就以码云的webhooks为例,实现服务端的代码自动同步部署。 了解 git 的 hooks 关于 git 钩子 Git 能在特定的重要动作发生时触发自定义脚本。 有两组这样的钩子:客户端的和服务器端的。 客户端钩子由诸如...

LoveSummer 4419

数据采集卡架构与PCIe优化设计详解

数据采集卡(DAQ)作为工业自动化中的关键设备,其核心在于模数转换(ADC)和数字信号处理技术。现代系统普遍采用PCIe总线架构,通过DMA传输和时钟同步技术实现高速数据采集。在信号调理环节,可编程增益放大器(PGA)和抗混叠滤波器确保信号质量;而Σ-Δ型ADC则提供高达24位的分辨率。实际应用中,从电力监测到机床振动分析,数据采集卡需要结合具体场景优化配置。通过合理的PCB布局和EMI防护设计,可以有效提升系统在工业环境中的可靠性。

weixin_29168675的博客 912

创新实训(五) RAG——知识库迁移+重新配置+数据向量化

因为要上传的文件很多且格式各不相同,方便起见,这里选择使用api传输,代码已经写好了,只需要改动配置文件就好了。首先是查看MVIDIA控制面板,然后点击系统信息,然后组件中查看cuda驱动版本:cuda为12.2版本。因为requirements中的torch是cpu版本的,所以这里要手动下载GPU的pytorch。目的是处理非结构化文本,对《周易研究》期刊的各个文章进行分词,向量化,建立索引,并存入知识库。回顾之前的配置,clash的代理端口是7890。修改gitconfig配置:c盘用户的主目录里。

qq_26245471的博客 2622

别再混淆了!一张图看懂SAP特殊采购类30/40/70/80的区别与选型指南

本文深度解析SAP特殊采购类30/40/70/80的核心逻辑与业务影响,通过对比框架和真实案例帮助用户掌握其适用边界。重点介绍委外加工(类型30)、工厂间转移(类型40/70)及计划与执行分离(类型80)的配置要点与常见问题,提供选型决策树和实施检查清单,助力企业优化供应链管理。

weixin_26938645的博客 458

qt5.14.2+vs2019配置msvc2017编译器

qt5.14.2+vs2019配置msvc2017编译器 在使用qt编译程序时此前一直使用的是自带的MinGW 32-bit和64-bit,现在想使用msvc编译器。本次使用的是qt5.14.2,vs2019,需要配置msvc2017的32-bit和64-bit编译器。 1、首先安装好qt5.14.2和vs2019,其次在visual studio installer选择修改,然后选择msvc2017对应的组件,本次安装的是这两个 2、打开qt creator的工具–选项–kits–编译器,选择Manu

bangtanhui的博客 1万+

Git Hooks实现开发部署任务自动化

[转]使用Git Hooks实现开发部署任务自动化 提供:ZStack社区 前言 版本控制,这是现代软件开发的核心需求之一。有了它,软件项目可以安全的跟踪代码变更并执行回溯、完整性检查、协同开发等多种操作。在各种版本控制软件中,Git是近年来最流行的软件之一,它的去中心化架构以及源码变更交换的速度被很多开发者青睐。 在git的众多优点中,最有用的一点莫过于它的灵活性。通过“hooks”(

Richard_Jason的专栏 1万+

解决k8s核心组件calico pod资源不创建问题

解决k8s核心组件calico pod资源不创建问题 1.问题描述 由于K8S集群Master节点故障,导致calico网络组件虽然处于Running状态,但是一直无法准备就绪,如下图所示 calico-node-lpt7h运行在master节点,第一时间紧急处理方法就是将其pod删除,让K8S自动重建该pod,使整个集群快速恢复 但是就当我将calico-node-lpt7h pod删除后,该pod始终无法自建,就好像是从来没有这个pod似的 2.解决方法 期初排查时,我觉得可能是由于当前master

江晓龙的博客 4808

Copaw:开发者自动化工作流工具,提升开发效率与部署一致性

在软件工程实践中,自动化是提升开发效率和保障流程一致性的核心手段。其原理在于通过脚本或工具将重复性手动操作转化为可重复执行的标准化流程,从而减少人为错误、释放开发者精力。从技术价值看,自动化不仅加速了本地开发、测试与构建环节,更是实现持续集成与持续部署(CI/CD)的基石。典型的应用场景包括代码检查、依赖管理、镜像构建、环境部署及测试验证等日常开发任务。本文聚焦的Copaw,正是一款面向开发者的命令行工作流自动化工具。它采用声明式的YAML配置定义任务序列,支持变量注入、条件执行与并行步骤,并能通过插件体系

weixin_38168590的博客 381

全新YOLOv11一文弄懂 | YOLOv11网络结构解读 、yolov11.yaml配置文件详细解读与说明、模型训练参数详细解析 | 通俗易懂!入门必看系列!

本文全面介绍了YOLOv11目标检测算法,包含网络结构解析、yaml配置文件详解及训练教程。YOLOv11通过改进的C3k2f模块、SPPF和C2PSA注意力机制等创新设计,在COCO数据集上实现了比YOLOv8更优的性能。文章详细解读了yolov11.yaml配置文件的参数设置、主干网络(backbone)和头部网络(head)结构,并提供了完整的训练代码示例和参数说明。训练部分涵盖了模型选择、参数设置及优化技巧,包括epochs、batch size、学习率等关键参数的调整建议。最后总结了YOLOv11

Ai缝合怪、助力小伙伴高效发论文 3万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Pi0具身智能v1一键部署教程:基于Git的版本控制与协作开发

本文介绍了如何在星图GPU平台上自动化部署Pi0 具身智能(内置模型版)v1镜像,快速构建开箱即用的具身智能开发环境。该镜像预装ROS 2、PyTorch与CUDA,支持机械臂抓取、物体分拣等典型具身交互任务,显著缩短环境配置时间,提升算法研发效率。

weixin_33245447的博客 90

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

构建开发者效率工具集:从自动化脚本到模块化工作坊

在软件工程实践中,自动化脚本和工具集是提升开发效率、保障项目一致性的关键技术手段。其核心原理在于将重复、繁琐的手动操作(如环境配置、依赖管理、代码检查、构建部署)封装为可复用的脚本,通过标准化和流程化减少人为错误与时间消耗。从技术价值看,这不仅实现了开发流程的规范化和可重复性,也为团队协作与持续集成/持续部署(CI/CD)奠定了坚实基础。典型的应用场景包括项目环境一键初始化、代码质量门禁、多环境构建与发布等。本文以“xiuxian-artisan-workshop”项目为例,深入探讨如何设计一个模块化、可扩

weixin_30363509的博客 328

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【开发工具】Git Hooks:打造高效自动化开发流

在人工智能和机器学习领域,Git Hooks 也能发挥重要作用。对于机器学习模型的训练和部署,每次模型的更新都可以视为一次代码提交,通过 Git Hooks 可以自动执行模型评估、性能监控等任务 。当模型的性能指标不满足要求时,阻止模型的更新,从而保证线上模型的质量和稳定性 。

大雨淅淅的博客 999

如何使用 Git 钩子 hooks 自动化任务?

使用 Git 钩子(hooks)自动化任务的方法是在 Git 仓库中创建和配置 hooks 脚本。Git hooks 是一些脚本,在特定的 Git 操作发生时触发。比如说提交代码(commit)、推送代码(push)或合并代码(merge)时,可以自动执行设定的任务。配置 Git hooks 时,你需要在项目的 目录下创建相应的脚本文件。这些脚本可以是 Shell、Python 或其他脚本语言。1) 类型分类 : Git hooks 分为客户端和服务端两种:2) 常见的客户端钩子 :3) 常见的服务器端钩

测试开发技术 851

利用Git Hooks实现代码推送后的自动化部署

本文详细介绍了如何利用Git Hooks实现代码推送后的自动化部署。通过配置服务器端的post-update钩子,可以在执行git push操作后自动触发部署脚本,将代码同步至应用服务器并完成更新、依赖安装及服务重启,从而构建一个轻量级、高效的自动化部署流程,特别适合中小团队及个人开发者。

l6m7n8的博客 484
上一篇: 如何利用Heartbeat与Floating IP在Ubuntu 14.04上创建高可用性设置
下一篇: 如何在Ubuntu 14.04之上安装Linux、Apache、MySQL与PHP(即LAMP)堆栈
普通网友
博客等级 码龄10年 769粉丝 269原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值