Skip to content

Commit

Permalink
[tools] upload release artifacts on SIT-MC server
Browse files Browse the repository at this point in the history
  • Loading branch information
liplum committed May 26, 2024
1 parent 4efdf99 commit 90bf207
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 123 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ jobs:
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Upload artifacts onto SIT-MC sever
run: |
node tools/upload-release-sitmc.mjs -k ${{ secrets.SITMC_TEMP_SERVER_AUTH }}
- name: Deploy
if: github.repository == 'liplum-dev/mimir'
shell: bash
run: |
node tools/publish-release.mjs
4 changes: 2 additions & 2 deletions tools/increment-build-number.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const pubspecPath = 'pubspec.yaml'
*
* @param {string} newVersion
*/
async function pushAndTagChanges(newVersion) {
const pushAndTagChanges = async (newVersion) => {
// Git operations (assuming arguments are provided)
const serverUrl = process.argv[2]
const repository = process.argv[3]
Expand All @@ -27,7 +27,7 @@ async function pushAndTagChanges(newVersion) {
])
}

async function main() {
const main = async () => {
// Read pubspec.yaml content
const filedata = await fs.readFile(pubspecPath, 'utf-8')

Expand Down
2 changes: 1 addition & 1 deletion tools/lib/bot.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @param {{botUrl: string,token:string, groupNumber:string,message:string}} param0
* @returns
*/
export async function sendMessageToQQGroup({ botUrl, groupNumber, message }) {
export const sendMessageToQQGroup = async ({ botUrl, groupNumber, message }) => {
const url = new URL(botUrl)
url.searchParams.append("group_id", groupNumber)
url.searchParams.append("message", message)
Expand Down
9 changes: 7 additions & 2 deletions tools/lib/git.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const github = context
* @param {string} tag
* @returns {[string, number]}
*/
export function extractVersionAndBuildNumberFromTag(tag) {
export const extractVersionAndBuildNumberFromTag = (tag) => {
const versionMatch = tag.match(/(\d+.\d+.\d+)/)
const buildNumberMatch = tag.match(/\d+.\d+.\d+(\+\d+)/)
const version = versionMatch[1]
Expand All @@ -24,9 +24,14 @@ export function extractVersionAndBuildNumberFromTag(tag) {
* Get the largest version and build number from current git repository
* @returns {Promise<[string, int]>}
*/
export async function getLargestTag() {
export const getLargestTag = async () => {
const tags = await git.tags()
// in ascending order
const versionInfos = tags.all.map(tag => extractVersionAndBuildNumberFromTag(tag)).sort((a, b) => a[1] - b[1])
return versionInfos[versionInfos.length - 1]
}


export const getGitHubMirrorDownloadUrl = (url) => {
return `https://mirror.ghproxy.com/${url}`
}
59 changes: 59 additions & 0 deletions tools/lib/release.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { git, github } from './lib/git.mjs'
import crypto from "crypto"

/**
* @param {({name:string,browser_download_url:string})=>boolean} filter
*/
export async function searchAndGetAssetInfo(filter) {
const asset = searchAsset(filter)
if (!asset) return
return await getAssetInfo(asset)
}

/**
* @template {{name:string,browser_download_url:string}} T
* @param {(T)=>boolean} filter
* @returns {T | undefined}
*/
function searchAsset(filter) {
const assets = github.release.assets
for (const asset of assets) {
if (filter(asset)) {
return asset
}
}
return
}

/**
*
* @param {{name:string,browser_download_url:string}} payload
*/
async function getAssetInfo(payload) {
const url = payload.browser_download_url
let sha256 = ""
if (url) {
sha256 = await downloadAndSha256Hash(url)
}
return {
name: payload.name,
url: url,
sha256: sha256,
}
}


/**
*
* @param {string} url
*/
async function downloadAndSha256Hash(url) {
const response = await fetch(url)
const chunks = []
for await (const chunk of response.body) {
chunks.push(chunk)
}
const buffer = Buffer.concat(chunks)
const hash = crypto.createHash('sha256').update(buffer).digest('hex')
return hash
}
3 changes: 2 additions & 1 deletion tools/lib/sitmc.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { readFile } from "fs/promises"
import * as path from "path"
import mime from 'mime'
import { sanitizeNameForUri } from "./utils.mjs"

const prodUrl = "https://temp.sitmc.club"
const debugUrl = "http://127.0.0.1:5000"
Expand Down Expand Up @@ -56,5 +57,5 @@ export async function deleteFile({ auth, remotePath }) {
* @param {{tagName:string,fileName:string}} param0
*/
export function getArtifactDownloadUrl({ tagName, fileName }) {
return `https://temp.sitmc.club/prepare-download/${tagName}/${fileName}`
return `https://temp.sitmc.club/prepare-download/${sanitizeNameForUri(tagName)}/${sanitizeNameForUri(fileName)}`
}
25 changes: 25 additions & 0 deletions tools/lib/utils.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import fs from "fs"
import { Readable } from "stream"
import { pipeline } from "stream/promises"
/**
*
* @param {string} raw
*/
export const sanitizeNameForUri = (raw) => {
return raw.replace("+", "-")
}


/**
*
* @param {string} url
* @param {string} filePath
*/
export const downloadFile = async (url, filePath) => {
const res = await fetch(url)

const s = fs.createWriteStream(filePath)
// Readable.fromWeb(res.body).pipe(s)
await pipeline(Readable.fromWeb(res.body), s)

}
132 changes: 33 additions & 99 deletions tools/publish-release.mjs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as fs from 'fs/promises' // For file system operations
import { git, github } from './lib/git.mjs'
import crypto from "crypto"
import { git, github, getGitHubMirrorDownloadUrl } from './lib/git.mjs'
import * as path from "path"
import { getArtifactDownloadUrl } from './lib/sitmc.mjs'
import esMain from 'es-main'
import { searchAndGetAssetInfo } from "./lib/release.mjs"

const gitUrl = 'https://github.com/Amazefcc233/mimir-docs'
const deployPath = '~/deploy'
const artifactPath = 'artifact/'

async function main() {
const main = async () => {
// Get release information from environment variables (GitHub Actions context)
const version = getVersion()
const releaseTime = getPublishTime()
Expand Down Expand Up @@ -43,11 +43,35 @@ async function main() {
await fs.unlink(`${artifactPath}latest.json`) // Ignore if file doesn't exist
await fs.symlink(`${version}.json`, `${artifactPath}latest.json`)

await addAndPush({ version })
await git.add(".")
await git.commit(`Release New Version: ${version}`)
await git.push("[email protected]:Amazefcc233/mimir-docs", "main:main")
}

function withGitHubMirror(url) {
return `https://mirror.ghproxy.com/${url}`

function getVersion() {
// remove leading 'v'
return github.release.tag_name.slice(1)
}

function getReleaseNote() {
const text = github.release.body
const startLine = text.indexOf('## 更改')
const endLine = text.indexOf('## How to download')

if (startLine === -1 || endLine === -1) {
throw new Error('Release notes section not found')
}

// Extract content between start and end lines (excluding headers)
const releaseNotes = text.substring(startLine + '## 更改\n'.length, endLine).trim()

// Remove any leading or trailing blank lines
return releaseNotes.replace(/^\s*|\s*$/g, '')
}

function getPublishTime() {
return new Date(github.release.published_at)
}

function buildArtifactPayload({ version, tagName, releaseTime, releaseNote, apk, ipa }) {
Expand All @@ -65,7 +89,7 @@ function buildArtifactPayload({ version, tagName, releaseTime, releaseNote, apk,
url: {
official: getArtifactDownloadUrl(tagName, apk.name),
github: apk.url,
mirror: withGitHubMirror(apk.url),
mirror: getGitHubMirrorDownloadUrl(apk.url),
},
}
}
Expand All @@ -77,14 +101,14 @@ function buildArtifactPayload({ version, tagName, releaseTime, releaseNote, apk,
url: {
official: getArtifactDownloadUrl(tagName, ipa.name),
github: ipa.url,
mirror: withGitHubMirror(ipa.url),
mirror: getGitHubMirrorDownloadUrl(ipa.url),
},
}
}
return payload
}

function validateArtifactPayload(payload) {
const validateArtifactPayload = (payload) => {
for (const [profile, download] in Object.entries(payload.downloads)) {
if (!(download.default && download.url[download.default] !== undefined)) {
if (download.url.length > 0) {
Expand All @@ -95,96 +119,6 @@ function validateArtifactPayload(payload) {
}
}
}
/**
*
* @param {{version:string}} param0
*/
async function addAndPush({ version }) {
await git.add(".")
await git.commit(`Release New Version: ${version}`)
await git.push("[email protected]:Amazefcc233/mimir-docs", "main:main")
}

function getVersion() {
// remove leading 'v'
return github.release.tag_name.slice(1)
}

function getReleaseNote() {
const text = github.release.body
const startLine = text.indexOf('## 更改')
const endLine = text.indexOf('## How to download')

if (startLine === -1 || endLine === -1) {
throw new Error('Release notes section not found')
}

// Extract content between start and end lines (excluding headers)
const releaseNotes = text.substring(startLine + '## 更改\n'.length, endLine).trim()

// Remove any leading or trailing blank lines
return releaseNotes.replace(/^\s*|\s*$/g, '')
}

function getPublishTime() {
return new Date(github.release.published_at)
}

/**
* @param {({name:string,browser_download_url:string})=>boolean} filter
*/
async function searchAndGetAssetInfo(filter) {
const asset = searchAsset(filter)
if (!asset) return
return await getAssetInfo(asset)
}

/**
* @template {{name:string,browser_download_url:string}} T
* @param {(T)=>boolean} filter
* @returns {T | undefined}
*/
function searchAsset(filter) {
const assets = github.release.assets
for (const asset of assets) {
if (filter(asset)) {
return asset
}
}
return
}

/**
*
* @param {{name:string,browser_download_url:string}} payload
*/
async function getAssetInfo(payload) {
const url = payload.browser_download_url
let sha256 = ""
if (url) {
sha256 = await downloadAndSha256Hash(url)
}
return {
name: payload.name,
url: url,
sha256: sha256,
}
}

/**
*
* @param {string} url
*/
async function downloadAndSha256Hash(url) {
const response = await fetch(url)
const chunks = []
for await (const chunk of response.body) {
chunks.push(chunk)
}
const buffer = Buffer.concat(chunks)
const hash = crypto.createHash('sha256').update(buffer).digest('hex')
return hash
}

if (esMain(import.meta)) {
main()
Expand Down
7 changes: 5 additions & 2 deletions tools/to-distro.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import esMain from 'es-main'
import fs from 'fs/promises' // For file system operations

const projectPbxprojPath = 'ios/Runner.xcodeproj/project.pbxproj'
Expand All @@ -9,7 +10,7 @@ const mapping = {
'PROVISIONING_PROFILE_SPECIFIER = "";': 'PROVISIONING_PROFILE_SPECIFIER = "SITLife-Distribution-AppStore";',
}

async function main() {
const main = async () => {
// Read project.pbxproj file content
let filedata = await fs.readFile(projectPbxprojPath, 'utf-8')

Expand All @@ -21,4 +22,6 @@ async function main() {
await fs.writeFile(projectPbxprojPath, filedata)
}

main()
if (esMain(import.meta)) {
main()
}
Loading

0 comments on commit 90bf207

Please sign in to comment.