使用 Golang 在 GitLab 上拉取代码并将静态资源部署到 Nginx,同时将图库上传至阿里云 OSS

使用 Golang 在 GitLab 上拉取代码并将静态资源部署到 Nginx,同时将图库上传至阿里云 OSS

本文章采用几个任务执行

最终想要实现效果,
1、golang做成一个服务占用一个端口,然后监测gitlab仓库webhook
2、前端人员提交代码到gitlab,golang触发去拉取代码,放到本地指定目录
3、go判断目录进行区分,静态资源,跟图库
4、静态资源上传到远程服务器html目录下
5、图库资源上传到阿里云OSS里面
6、刷新一下CDN缓存

目前没有服务化,尝试监听gitlab的webhook,但是推送代码,golang没有触发,目前还在解决中。。。。。

以下是源代码

任务一拉取代码

代码如下

//这个是需要手动执行,没有做成服务
package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"
)

func main() {
	// 判断当前环境是否有 Git
	//if _, err := exec.LookPath("git"); err != nil {
	//  fmt.Println("当前没有Git环境,建议你安装一下Git环境")
	//  return
	//}

	// 执行 git clone 命令克隆代码仓库,并输入账户密码
	fmt.Println("开始执行 git clone 命令...")
	cmd1 := exec.Command("git", "clone", "-b", "oss", "xxxxx", "D:/impromptu")
	cmd1.Stdin = os.Stdin
	cmd1.Stdout = os.Stdout
	cmd1.Stderr = os.Stderr
	cmd1.Env = append(cmd1.Env, "GIT_TERMINAL_PROMPT=1")
	cmd1.Env = append(cmd1.Env, "GIT_ASKPASS=")
	cmd1.Run()
	fmt.Println("oss代码已经拉取下来,存放在本地:D:/impromptu")

	//执行上传文件到linux静态资源文件
	fmt.Println("开始上传文件到 Linux服务器...")
	cmd := exec.Command("E:/go/goproject/src/go_code/project01/upload.exe")
	out1, err := cmd.Output()
	if err != nil {
		fmt.Println(err)
		return
	}
	if strings.Contains(string(out1), "successfully") {
		fmt.Println("上传文到服务器 执行成功,请到浏览器刷新查看是否更新")
	} else {
		fmt.Println("你的文件上传到服务器失败,请查看问题!")
	}

	//执行 上传文件到oss Go 文件
	fmt.Println("开始上传文件到 OSS...")
	cmd2 := exec.Command("E:/go/goproject/src/go_code/golang01/oss.exe")
	out, err := cmd2.Output()
	if err != nil {
		fmt.Println(err)
		return
	}
	if strings.Contains(string(out), "successfully") {
		fmt.Println("上传oss文件执行成功,请到oss查看文件是否存在")
	} else {
		fmt.Println("你的oss上传文件失败,请查看问题!")
	}

	// 执行刷新cdn缓存 Go 文件
	fmt.Println("执行刷新cdn缓存 Go 文件...")
	cmd3 := exec.Command("E:/go/goproject/src/go_code/golang02/cdn.exe")
	out2, err := cmd3.Output()
	if err != nil {
		fmt.Println(err)
		return
	}
	if strings.Contains(string(out2), "successfully") {
		fmt.Println("刷新cdn缓存文件执行成功,请到CDN查看操作记录")
	} else {
		fmt.Println("你的刷新cdn缓存失败,请查看问题!")
	}
}

执行结果

image-20230608143534636

查看有没有拉取代码下来

image-20230608143617585

任务二上传静态文件到服务器

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
)

func main() {
	// 获取远程服务器地址和 port
	host := "xxx"
	port := "xxxx"

	// 获取远程服务器用户名和登录密码
	user := "root"
	password := "xxxx"

	// 获取本地文件路径和文件名
	localPath := "D:\\impromptu\\web" // 本地文件夹路径

	// 获取远程服务器目标路径
	remotePath := "/front/nginx/html/test/web" // 远程目录路径

	// 建立 SSH 连接
	config := &ssh.ClientConfig{
		User: user,
		Auth: []ssh.AuthMethod{
			ssh.Password(password),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}
	conn, err := ssh.Dial("tcp", host+":"+port, config)
	if err != nil {
		fmt.Printf("无法连接到远程服务器:%s\n", err.Error())
		os.Exit(1)
	}
	defer conn.Close()

	// 建立 SFTP 客户端
	client, err := sftp.NewClient(conn)
	if err != nil {
		fmt.Printf("创建 SFTP 客户端失败:%s\n", err.Error())
		os.Exit(1)
	}
	defer client.Close()

	// 遍历本地目录中的文件,并上传到远程服务器
	err = filepath.Walk(localPath, func(filePath string, info os.FileInfo, err error) error {
		if err != nil {
			fmt.Printf("遍历本地目录失败:%s\n", err.Error())
			return err
		}

		// 判断是否是目录,如果是则创建远程目录
		if info.IsDir() {
			// 获取相对路径,并拼接到远程目录路径上
			relativePath := strings.TrimPrefix(filePath, localPath)
			remoteDir := filepath.ToSlash(filepath.Join(remotePath, relativePath))

			err = client.MkdirAll(remoteDir)
			if err != nil {
				fmt.Printf("创建远程目录失败:%s\n", err.Error())
				return err
			}
			fmt.Printf("已在远程服务器上创建目录:%s\n", remoteDir)
		} else {
			// 读取文件内容并上传到远程服务器
			fileBytes, err := ioutil.ReadFile(filePath)
			if err != nil {
				fmt.Printf("读取本地文件失败:%s\n", err.Error())
				return err
			}

			// 获取文件名,并拼接到远程目录路径上
			fileName := info.Name()
			remoteFile := filepath.ToSlash(filepath.Join(remotePath, fileName))

			remoteWriter, err := client.Create(remoteFile)
			if err != nil {
				fmt.Printf("在远程服务器上创建文件失败:%s\n", err.Error())
				return err
			}

			_, err = remoteWriter.Write(fileBytes)
			if err != nil {
				fmt.Printf("向远程服务器写入文件内容失败:%s\n", err.Error())
				return err
			}
			fmt.Printf("已将本地文件 %s 上传到远程服务器:%s\n", filePath, remoteFile)
		}

		return nil
	})

	if err != nil {
		fmt.Printf("上传文件失败:%s\n", err.Error())
		os.Exit(1)
	}

	fmt.Println("文件上传完成!successfully.")
}

执行结果

image-20230608143805708

查看服务器上面有没有资源

image-20230608143841662

任务三上-图库到阿里云OSS

// 这个是分资源上传到oss
package main

import (
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	// 阿里云OSS相关配置信息
	endpoint := "xxxxx"
	accessKeyId := "xxxx"
	accessKeySecret := "xxxx"
	bucketName := "oss-cicd"

	// 创建阿里云OSS客户端
	client, err := oss.New(endpoint, accessKeyId, accessKeySecret)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 获取要操作的Bucket
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 定义本地目录和OSS目录
	localDir := "D:/impromptu/oss/"
	ossDir := "oss/"

	// 递归遍历本地目录下所有文件和子目录
	err = filepath.Walk(localDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		// 如果是子目录,则在OSS上创建同名目录
		if info.IsDir() {
			dirName := strings.TrimPrefix(strings.ReplaceAll(path, "\\", "/"), localDir)
			if dirName == "" {
				return nil
			}
			ossPath := filepath.ToSlash(filepath.Join(ossDir, dirName)) + "/"
			fmt.Printf("Creating OSS directory %s\n", ossPath)
			err = bucket.PutObject(ossPath, strings.NewReader(""))
			if err != nil {
				return err
			}
		} else {
			// 如果是文件,则上传到OSS中对应的目录
			fileName := strings.TrimPrefix(strings.ReplaceAll(path, "\\", "/"), localDir)
			ossPath := filepath.ToSlash(filepath.Join(ossDir, fileName))
			fmt.Printf("Uploading file %s to OSS path %s\n", path, ossPath)

			// 读取本地文件内容
			content, err := ioutil.ReadFile(path)
			if err != nil {
				return err
			}

			// 上传文件到OSS
			err = bucket.PutObject(ossPath, strings.NewReader(string(content)))
			if err != nil {
				return err
			}
		}

		return nil
	})

	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	fmt.Println("All objects uploaded successfully.")
}

执行结果

image-20230608144043405

查看阿里云OSS
image-20230608144119259

任务四-刷新阿里云CDN

这一步如果你们没有CDN可以忽略,我们有配置cdn内容分发网络,每次更新都需要刷新一下缓存

// This file is auto-generated, don't edit it. Thanks.
package main

import (
	"fmt"
	cdn "github.com/alibabacloud-go/cdn-20180510/v2/client"
	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
)

/**
 * 使用AK&SK初始化账号Client
 * @param accessKeyId
 * @param accessKeySecret
 * @return Client
 * @throws Exception
 */
func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *cdn.Client, _err error) {
	config := &openapi.Config{
		// 必填,您的 AccessKey ID
		AccessKeyId: accessKeyId,
		// 必填,您的 AccessKey Secret
		AccessKeySecret: accessKeySecret,
	}
	// 访问的域名
	config.Endpoint = tea.String("cdn.aliyuncs.com")
	_result = &cdn.Client{}
	_result, _err = cdn.NewClient(config)
	return _result, _err
}

func _main() (_err error) {
	// 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
	// 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用,仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378661.html
	client, _err := CreateClient(tea.String("xxxx"), tea.String("xxxx"))
	if _err != nil {
		return _err
	}

	refreshObjectCachesRequest := &cdn.RefreshObjectCachesRequest{
		ObjectPath: tea.String("https://xxxx.com/"),
		ObjectType: tea.String("Directory"),
	}
	runtime := &util.RuntimeOptions{}
	tryErr := func() (_e error) {
		defer func() {
			if r := tea.Recover(recover()); r != nil {
				_e = r
			}
		}()
		// 复制代码运行请自行打印 API 的返回值
		_, _err = client.RefreshObjectCachesWithOptions(refreshObjectCachesRequest, runtime)
		if _err != nil {
			return _err
		}

		return nil
	}()

	if tryErr != nil {
		var error = &tea.SDKError{}
		if _t, ok := tryErr.(*tea.SDKError); ok {
			error = _t
		} else {
			error.Message = tea.String(tryErr.Error())
		}
		// 如有需要,请打印 error
		_, _err = util.AssertAsString(error.Message)
		fmt.Println(_err)
		if _err != nil {
			return _err
		}
	}
	return _err
}

func main() {
	err := _main()
	if err != nil {
		panic(err)
	}
	fmt.Println("完成刷新CDN缓存 successfully.")
}

ea.SDKError{}
if _t, ok := tryErr.(*tea.SDKError); ok {
error = _t
} else {
error.Message = tea.String(tryErr.Error())
}
// 如有需要,请打印 error
_, _err = util.AssertAsString(error.Message)
fmt.Println(_err)
if _err != nil {
return _err
}
}
return _err
}

func main() {
err := _main()
if err != nil {
panic(err)
}
fmt.Println(“完成刷新CDN缓存 successfully.”)
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将Go和数据库连接使用部署到云服务器上的步骤: 1. 安装Go 在云服务器上安装Go语言,可以通过官方网站下载安装包,或者通过包管理器进行安装。 例如,Ubuntu系统可以通过以下命令安装Go: ``` sudo apt-get update sudo apt-get install golang ``` 2. 安装数据库 在云服务器上安装需要使用的数据库,例如MySQL、PostgreSQL等。可以通过包管理器或者官方网站下载安装包进行安装。 3. 安装数据库驱动 Go需要使用相应的数据库驱动才能连接到数据库,可以通过以下命令安装: ``` go get github.com/go-sql-driver/mysql ``` 这里以MySQL为例,如果使用其他数据库,需要安装相应的驱动。 4. 编写Go代码 使用Go语言编写代码,连接到数据库并进行操作。例如: ``` import ( "database/sql" _ "github.com/go-sql-driver/mysql" ) func main() { db, err := sql.Open("mysql", "user:password@tcp(host:port)/database") if err != nil { panic(err.Error()) } defer db.Close() // 进行数据库操作 } ``` 这里需要将`user`、`password`、`host`、`port`和`database`替换为实际的值。 5. 部署到云服务器 将编写好的代码部署到云服务器上,可以使用FTP、SCP等工具上传文件,也可以使用Git等版本控制工具进行部署。 6. 运行代码 在云服务器上运行代码,可以使用以下命令: ``` go run main.go ``` 或者编译为可执行文件后运行: ``` go build main.go ./main ``` 这样就可以将Go和数据库连接使用部署到云服务器上了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值