Skip to content

Commit

Permalink
feat: await what GitHub RAW file and repo file are synced
Browse files Browse the repository at this point in the history
  • Loading branch information
piquark6046 committed Feb 16, 2024
1 parent 9636e80 commit 51b9188
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
10 changes: 9 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {ListBranches} from './sources/branches.js'
import {CommitManager} from './sources/commits.js'
import {PurgeRequestManager} from './sources/requests.js'
import {GetIPAddress} from './sources/ipcheck.js'
import {GitHubRAWHash} from './sources/hash.js'
import * as Actions from '@actions/core'
import * as Os from 'node:os'

Expand Down Expand Up @@ -40,8 +41,15 @@ const ProgramOptions = ReplaceStringWithBooleanInObject(ProgramRawOptions) as Ty
Actions.info(`The runner's IP address: ${await GetIPAddress().then(IPAddress => IPAddress)}`)

// Workflow
const LatestWorkflowRunTime = await GetLatestWorkflowTime(ProgramOptions).then(LatestWorkflowRunTime => LatestWorkflowRunTime)
const Branches = await ListBranches(ProgramOptions).then(Branches => Branches)
// Hold until checking hash is done.
const GitHubRAWHashInstance = new GitHubRAWHash(ProgramOptions, Branches)
GitHubRAWHashInstance.Initialize()
await GitHubRAWHashInstance.Register()
await GitHubRAWHashInstance.Check()
Actions.info('Checking hash is passed.')

const LatestWorkflowRunTime = await GetLatestWorkflowTime(ProgramOptions).then(LatestWorkflowRunTime => LatestWorkflowRunTime)
const PurgeRequest = new PurgeRequestManager(ProgramOptions)
for (const Branch of Branches) {
const CommitManagerInstance = new CommitManager(ProgramOptions, Branches)
Expand Down
96 changes: 96 additions & 0 deletions sources/hash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import * as Hashes from '@noble/hashes/sha3'

Check failure on line 1 in sources/hash.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Cannot find module '@noble/hashes/sha3' or its corresponding type declarations.

Check failure on line 1 in sources/hash.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Cannot find module '@noble/hashes/sha3' or its corresponding type declarations.
import * as HashesUtils from '@noble/hashes/utils'

Check failure on line 2 in sources/hash.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Cannot find module '@noble/hashes/utils' or its corresponding type declarations.

Check failure on line 2 in sources/hash.ts

View workflow job for this annotation

GitHub Actions / Run ESLint

Cannot find module '@noble/hashes/utils' or its corresponding type declarations.
import * as Git from 'simple-git'
import got from 'got'
import Os from 'node:os'
import type * as Types from './types.js'

async function GetFileFromGitHubRAW(ProgramOptions: Types.ProgramOptionsType, BranchOrTag: string, Filename: string): Promise<Uint8Array> {
const Raw = await got(`https://github.com/${ProgramOptions.repo}/raw/${BranchOrTag}/${Filename}`, {
https: {
minVersion: 'TLSv1.3',
ciphers: 'TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256',
},
http2: true,
}).text()
return new TextEncoder().encode(Raw)
}

function GetSHA3FromUint8Array(Uint8Data: Uint8Array): string {
const HashUint8 = Hashes.sha3_256(Uint8Data)
return HashesUtils.bytesToHex(HashUint8)
}

function CreateGitInstance(BasePath: string): Git.SimpleGit {
const GitInstance = Git.simpleGit(BasePath, {maxConcurrentProcesses: Os.cpus().length})
return GitInstance
}

async function ListFileNamesInRepo(ProgramOptions: Types.ProgramOptionsType, Branch: string): Promise<string[]> {
const GitInstance = CreateGitInstance(ProgramOptions.ciWorkspacePath)
const FilenamesRaw = await GitInstance.raw(['ls-tree', '-r', '--name-only', Branch]).then(FileNames => FileNames.split('\n'))
return FilenamesRaw.filter(Filename => Filename.length > 0)
}

async function ReadFileAsUint8Array(ProgramOptions: Types.ProgramOptionsType, BranchOrTag: string, Filename: string): Promise<Uint8Array> {
const GitInstance = CreateGitInstance(ProgramOptions.ciWorkspacePath)
return GitInstance.show([`${BranchOrTag}:${Filename}`]).then(Target => new TextEncoder().encode(Target))
}

export class GitHubRAWHash {
private readonly Branches: string[] = []
private readonly GitHubRAWHashMap = new Map<{Branch: string; Filename: string}, string>()

constructor(private readonly ProgramOptions: Types.ProgramOptionsType, private readonly BranchesOrTag: string[]) {}

Initialize() {
this.Branches.push(...this.BranchesOrTag.filter(BranchOrTag => BranchOrTag !== 'latest'))
}

async Register() {
const PromiseList: Array<Promise<void>> = []
for (const Branch of this.Branches) {
// eslint-disable-next-line no-await-in-loop
for (const Filename of await ListFileNamesInRepo(this.ProgramOptions, Branch)) {
// eslint-disable-next-line no-async-promise-executor
PromiseList.push(new Promise(async Resolve => {
const Uint8Data = await ReadFileAsUint8Array(this.ProgramOptions, Branch, Filename)
const SHA3 = GetSHA3FromUint8Array(Uint8Data)
this.GitHubRAWHashMap.set({Branch, Filename}, SHA3)
Resolve()
}))
}
}

await Promise.all(PromiseList)
}

async Check() {
const PromiseList: Array<Promise<void>> = []
for (const Branch of this.Branches) {
// eslint-disable-next-line no-await-in-loop
for (const Filename of await ListFileNamesInRepo(this.ProgramOptions, Branch)) {
// eslint-disable-next-line no-async-promise-executor
PromiseList.push(new Promise(async Resolve => {
for (var I = 0; I < Number.MAX_SAFE_INTEGER; I++) {
// eslint-disable-next-line no-await-in-loop
const Uint8Data = await GetFileFromGitHubRAW(this.ProgramOptions, Branch, Filename)
const SHA3 = GetSHA3FromUint8Array(Uint8Data)
if (this.GitHubRAWHashMap.get({Branch, Filename}) === SHA3) {
break
}

// eslint-disable-next-line no-await-in-loop
await new Promise(Resolve => {
setTimeout(Resolve, 500)
})
}

Resolve()
}))
}
}

await Promise.all(PromiseList)
}
}

0 comments on commit 51b9188

Please sign in to comment.