摘要

起因是公司电脑使用的Win11 23H2的预览版,这个预览版系统的生命周期只到2024-09-18,到期后就会强制每两小时重启。这是Windows强制升级系统的一种手段。

虽然公司里的台式电脑目前用不到,但是里面还保留许多旧项目的资料,所以为了保留数据,我需要尽快转为正式版。

正文

一、编译IOS镜像

1.1 编译

起因是公司电脑使用的Win11 23H2的预览版,这个预览版系统的生命周期只到2024-09-18,到期后就会强制每两小时重启。这是Windows强制升级系统的一种手段。

虽然公司里的台式电脑目前用不到,但是里面还保留许多旧项目的资料,所以为了保留数据,我需要尽快转为正式版。

目前Windows 11系统正式版已经更新到了24H2版本,不过总体体验并不好。很多自带功能是强制捆绑给用户使用的,且没有开放给用户关闭或者切换开关。

我需要保留新系统的新特性,并且我还不要强制捆绑给用户使用的那些功能。结合自己的使用经历、以及查阅官方文档,确定了要制作Win11 22H2 22621.2283这个版本的镜像。

image-20240622191516498.png

访问UUPdump这个平台,根据自己的架构,选择对应的系统版本。

UUPdump 是一个社区驱动的网站和工具,旨在帮助用户下载和生成 Windows 更新包,注意这并不是由官方维护的!

image-20240622192326931.png

下载工具后,完成IOS镜像的编译。

image-20240622192402401.png

之后进行镜像的安装。

image-20240622192818418.png

等待安装完毕即可。

image-20240622194815453.png

1.2 参考致谢

2023 年 9 月 12 日 — KB5030219 (OS 内部版本 22621.2283) - Microsoft 支持

UUP dump

二、文件分片与合并

编译后的镜像,想从上海传给武汉的电脑,就需要一个不限速的服务作为媒介。我尝试了123网盘,但是这个盘下载时的网络经常断不稳定,故使用了小米云盘,但是小米云盘又限制单个文件大小。

由此我编写了文件分片与合并服务

  • 单线程顺序将文件进行分片与合并
  • 使用内存缓冲区技术。即使操作很大的文件,运行内存也只会在1MB左右
  • 通过命令行选项使用

放一张运行图。

image-20240622193606671.png

这种工具使用Go来写会好很多,但是Go本身又不熟悉,用不精通。就比如如何在运行时,更精巧地压榨程序内存、发挥更大性能,在这一块上没有Java用得精。

想把Jar编译成EXE,发现JavaGraalvm好垃圾,居然不支持日志组件SLFJ,我排查了后,发现是因为SLFJ中用到了好多反射,导致Graalvm失效。

三、配置GithubActions

3.1 Java

我的需求是按照如下图实现功能。

image-20240622170126178.png

创建目录.github/workflows,在该目录下随意创建一个yml文件。比如build.yml,内容如下。

yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Build, Package, and Release Java Project

on:
  push:
    tags:
      - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

# 在push或者pull_request时触发
# on:
#   push:
#     branches: [ "master" ]
#   pull_request:
#     branches: [ "master" ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Set up JDK 8
        uses: actions/setup-java@v3
        with:
          java-version: '8'
          distribution: 'temurin'
          cache: maven
      # 构建jar包
      - name: Build with Maven
        run: mvn package -DskipTests
      - run: mkdir staging && cp target/*.jar staging
      # 上传打包后内容到artifact
      - name: Upload JAR artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ github.ref_name }}
          path: staging
          retention-days: 1  # 设置保留 artifact 天数
      # 创建release
      - name: Create GitHub Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release-${{ github.ref }}
          draft: false
          prerelease: false
      # 将软件包打成zip压缩包
      - run: zip  ${{ github.ref_name }}.zip staging/*
      # 将zip压缩包上传至release
      - name: Upload JAR to Release
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path:  ${{ github.ref_name }}.zip
          asset_name:  ${{ github.ref_name }}.zip
          asset_content_type: application/zip

期间,遇到了 Resource not accessible by integration 这个错误,是因为 Actions 没有写权限导致的,按照下图进行授权即可。

image-20240721232732554.png

最终执行结果

image-20240622170307614.png

3.2 Go

踩坑相关的,参照上面Java的Action即可。下面放一个Golang多平台编译的Action,更直观的学习Action。

image-20250507152626863.png

image-20250507152809726.png

yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
name: Build, Package, and Release Go Binaries

on:
  push:
    tags:
      - 'v*'  # 只有打 tag 的时候才触发(可改为 push/main 等)

# 在push或者pull_request时触发
# on:
#   push:
#     branches: [ "master" ]
#   pull_request:
#     branches: [ "master" ]

jobs:
  # 因为创建release是个一次性操作。如果放到steps里面,就会出现被创建多次,然后报错的问题。
  create-release:
    runs-on: ubuntu-latest
    steps:
      # 创建 release
      - name: Create GitHub Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release-${{ github.ref }}
          draft: false
          prerelease: false

  # build依赖create-release
  build:
    needs: create-release
    runs-on: ubuntu-latest

    # 遍历 strategy.matrix 中的所有组合,这能让工作流针对矩阵里的每一种组合都执行一次 steps。
    strategy:
      matrix:
        os: [ windows,linux,darwin ]       # 三个平台:Windows、Linux、macOS
        arch: [ amd64,arm64 ]               # amd64、arm64 等架构

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.20.0' # 根据你的 Go 版本修改

      - name: Build binary
        env:
          GOOS: ${{ matrix.os }}
          GOARCH: ${{ matrix.arch }}
        run: |
          mkdir -p dist/
          EXT=""
          if [ "${GOOS}" = "windows" ]; then
            EXT=".exe"
          fi
          echo "current GOOS: ${GOOS}"
          echo "EXT: ${EXT}"
          go build -o dist/hash-it_${{ github.ref_name }}_${{ matrix.os }}_${{ matrix.arch }}${EXT} .
          echo "$(ls dist)"
      - name: Create zip file
        env:
          GOOS: ${{ matrix.os }}
          GOARCH: ${{ matrix.arch }}
        run: |
          cd dist
          EXT=""
          if [ "${GOOS}" = "windows" ]; then
            EXT=".exe"
          fi
          echo "current GOOS: ${GOOS}"
          echo "EXT: ${EXT}"
          zip -r hash-it_${{ github.ref_name }}_${{ matrix.os }}_${{ matrix.arch }}.zip hash-it_${{ github.ref_name }}_${{ matrix.os }}_${{ matrix.arch }}${EXT}
          echo "$(ls)"

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        env:
          GOOS: ${{ matrix.os }}
          GOARCH: ${{ matrix.arch }}
        with:
          name: hash-it_${{ github.ref_name }}_${{ matrix.os }}_${{ matrix.arch }}
          path: dist/hash-it_${{ github.ref_name }}_${{ matrix.os }}_${{ matrix.arch }}.zip
          retention-days: 1  # 设置保留 artifact 天数

      # 上传附件到Release
      - name: Upload zip files to Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          for zip_file in dist/*.zip; do
            asset_name=$(basename $zip_file)
            gh release upload ${{ github.ref_name }} $zip_file --clobber
          done

3.3 参考致谢

Quickstart for GitHub Actions - GitHub Docs

Contexts - GitHub Docs

Create Release Error in Github Actions - Developers: Plugin & API - Obsidian Forum

Building and testing Java with Maven - GitHub Docs

starter-workflows/ci at main · actions/starter-workflows

actions/upload-release-asset: An Action to upload a release asset via the GitHub Release API