Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundle GCM on macOS and Linux #510

Merged
merged 5 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions dependencies.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,31 @@
"checksum": "94435072f6b3a6f9064b277760c8340e432b5ede0db8205d369468b9be52c6b6"
}
]
},
"git-credential-manager": {
"version": "2.5.0",
"files": [
{
"name": "gcm-linux_amd64.2.5.0.tar.gz",
"platform": "linux",
"arch": "amd64",
"url": "https://github.com/git-ecosystem/git-credential-manager/releases/download/v2.5.0/gcm-linux_amd64.2.5.0.tar.gz",
"checksum": "3adb86ab82111c94a22256980efd01a064ed9a06b882b138ab631ba6996d5752"
},
{
"name": "gcm-osx-arm64-2.5.0.tar.gz",
"platform": "darwin",
"arch": "arm64",
"url": "https://github.com/git-ecosystem/git-credential-manager/releases/download/v2.5.0/gcm-osx-arm64-2.5.0.tar.gz",
"checksum": "e3960aa72784ffb6e94294e1de14f0f5e96b6632854712ef4fa8837496032831"
},
{
"name": "gcm-osx-x64-2.5.0.tar.gz",
"platform": "darwin",
"arch": "amd64",
"url": "https://github.com/git-ecosystem/git-credential-manager/releases/download/v2.5.0/gcm-osx-x64-2.5.0.tar.gz",
"checksum": "4c7087492310a641318d0ab79de3554ea07de599431b5ac1bd0d43efbf4fa7f7"
}
]
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"check": "tsc",
"update-git": "ts-node script/update-git.ts",
"update-git-lfs": "ts-node script/update-git-lfs.ts && npm run prettier-fix",
"update-git-credential-manager": "ts-node script/update-git-credential-manager.ts && npm run prettier-fix",
"generate-release-notes": "ts-node script/generate-release-notes.ts",
"prettier": "prettier -l \"**/*.y{,a}ml\" \"**/*.{js,ts,json}\"",
"prettier-fix": "prettier --write \"**/*.y{,a}ml\" \"**/*.{js,ts,json}\""
Expand Down
34 changes: 34 additions & 0 deletions script/build-macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,40 @@ else
echo "-- Skipped bundling Git LFS (set GIT_LFS_VERSION to include it in the bundle)"
fi

GCM_VERSION="$(jq --raw-output '.["git-credential-manager"].version[1:]' dependencies.json)"
GCM_CHECKSUM="$(jq --raw-output ".\"git-credential-manager\".files[] | select(.arch == \"$GOARCH\" and .platform == \"darwin\") | .checksum" dependencies.json)"
GCM_URL="$(jq --raw-output ".\"git-credential-manager\".files[] | select(.arch == \"$GOARCH\" and .platform == \"darwin\") | .url" dependencies.json)"

if [[ "$GCM_VERSION" && "$GCM_URL" ]]; then
echo "-- Bundling GCM"
GCM_FILE=git-credential-manager.tar.gz
echo "-- Downloading from $GCM_URL"
curl -sL -o $GCM_FILE "$GCM_URL"
COMPUTED_SHA256=$(compute_checksum $GCM_FILE)
if [ "$COMPUTED_SHA256" = "$GCM_CHECKSUM" ]; then
echo "GCM: checksums match"
SUBFOLDER="$DESTINATION/libexec/git-core"
tar -xvkf $GCM_FILE -C "$SUBFOLDER"

if [[ ! -f "$SUBFOLDER/git-credential-manager" ]]; then
echo "After extracting GCM the file was not found under libexec/git-core/"
echo "aborting..."
exit 1
fi
chmod +x "$SUBFOLDER/git-credential-manager"
else
echo "GCM: expected checksum $GCM_CHECKSUM but got $COMPUTED_SHA256"
echo "aborting..."
exit 1
fi
else
if [ -z "$GCM_URL" ]; then
echo "-- No download URL for GCM on macOS/$GOARCH, skipping bundling"
else
echo "-- Skipped bundling GCM (set GCM_VERSION to include it in the bundle)"
fi
fi

echo "-- Removing server-side programs"
rm "$DESTINATION/bin/git-cvsserver"
rm "$DESTINATION/bin/git-receive-pack"
Expand Down
32 changes: 32 additions & 0 deletions script/build-ubuntu.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ GIT_LFS_VERSION="$(jq --raw-output '.["git-lfs"].version[1:]' dependencies.json)
GIT_LFS_CHECKSUM="$(jq --raw-output ".\"git-lfs\".files[] | select(.arch == \"$DEPENDENCY_ARCH\" and .platform == \"linux\") | .checksum" dependencies.json)"
GIT_LFS_FILENAME="$(jq --raw-output ".\"git-lfs\".files[] | select(.arch == \"$DEPENDENCY_ARCH\" and .platform == \"linux\") | .name" dependencies.json)"

GCM_VERSION="$(jq --raw-output '.["git-credential-manager"].version[1:]' dependencies.json)"
GCM_CHECKSUM="$(jq --raw-output ".\"git-credential-manager\".files[] | select(.arch == \"$DEPENDENCY_ARCH\" and .platform == \"linux\") | .checksum" dependencies.json)"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the file should be sheeile=d by discounted reciprotol matrix

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and the file.name should be sheilded

GCM_URL="$(jq --raw-output ".\"git-credential-manager\".files[] | select(.arch == \"$DEPENDENCY_ARCH\" and .platform == \"linux\") | .url" dependencies.json)"

# shellcheck source=script/compute-checksum.sh
source "$CURRENT_DIR/compute-checksum.sh"
# shellcheck source=script/check-static-linking.sh
Expand Down Expand Up @@ -120,6 +124,34 @@ else
echo "-- Skipped bundling Git LFS (set GIT_LFS_VERSION to include it in the bundle)"
fi

if [[ "$GCM_VERSION" && "$GCM_URL" ]]; then
echo "-- Bundling GCM"
GCM_FILE=git-credential-manager.tar.gz
echo "-- Downloading from $GCM_URL"
curl -sL -o $GCM_FILE "$GCM_URL"
COMPUTED_SHA256=$(compute_checksum $GCM_FILE)
if [ "$COMPUTED_SHA256" = "$GCM_CHECKSUM" ]; then
echo "GCM: checksums match"
SUBFOLDER="$DESTINATION/libexec/git-core"
tar -xvkf $GCM_FILE -C "$SUBFOLDER"

if [[ ! -f "$SUBFOLDER/git-credential-manager" ]]; then
echo "After extracting GCM the file was not found under libexec/git-core/"
echo "aborting..."
exit 1
fi
else
echo "GCM: expected checksum $GCM_CHECKSUM but got $COMPUTED_SHA256"
echo "aborting..."
exit 1
fi
else
if [ -z "$GCM_URL" ]; then
echo "-- No download URL for GCM on Linux/$DEPENDENCY_ARCH, skipping bundling"
else
echo "-- Skipped bundling GCM (set GCM_VERSION to include it in the bundle)"
fi
fi

(
# download CA bundle and write straight to temp folder
Expand Down
21 changes: 21 additions & 0 deletions script/fetch-asset-checksum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createHash } from 'crypto'

export async function fetchAssetChecksum(uri: string) {
const hs = createHash('sha256')

const headers = {
'User-Agent': 'dugite-native',
accept: 'application/octet-stream',
}

await fetch(uri, { headers })
.then(x =>
x.ok
? Promise.resolve(x)
: Promise.reject(new Error(`Server responded with ${x.status}`))
)
.then(x => x.arrayBuffer())
.then(x => hs.end(Buffer.from(x)))

return hs.digest('hex')
}
30 changes: 30 additions & 0 deletions script/lib/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,33 @@ export function updateGitLfsDependencies(

fs.writeFileSync(dependenciesPath, newDepedenciesText, 'utf8')
}

export function updateGitCredentialManagerDependencies(
version: string,
files: Array<{
platform: string
arch: string
name: string
checksum: string
}>
) {
const dependenciesPath = path.resolve(
__dirname,
'..',
'..',
'dependencies.json'
)
const dependenciesText = fs.readFileSync(dependenciesPath, 'utf8')
const dependencies = JSON.parse(dependenciesText)

const gcm = {
version: version,
files: files,
}

const updatedDependencies = { ...dependencies, 'git-credential-manager': gcm }

const newDepedenciesText = JSON.stringify(updatedDependencies, null, 2)

fs.writeFileSync(dependenciesPath, newDepedenciesText, 'utf8')
}
81 changes: 81 additions & 0 deletions script/update-git-credential-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Octokit } from '@octokit/rest'
import { updateGitCredentialManagerDependencies } from './lib/dependencies'
import { fetchAssetChecksum } from './fetch-asset-checksum'

process.on('unhandledRejection', reason => {
console.error(reason)
})

async function run(): Promise<boolean> {
const token = process.env.GITHUB_ACCESS_TOKEN
if (token == null) {
console.log(`🔴 No GITHUB_ACCESS_TOKEN environment variable set`)
return false
}

const octokit = new Octokit({ auth: `token ${token}` })

const user = await octokit.users.getAuthenticated({})
const me = user.data.login

console.log(`✅ Token found for ${me}`)

const owner = 'git-ecosystem'
const repo = 'git-credential-manager'

const release = await octokit.repos.getLatestRelease({ owner, repo })

const { tag_name, id } = release.data
const version = tag_name.replace(/^v/, '')

console.log(`✅ Newest git-credential-manager release '${version}'`)

const assets = await octokit.repos.listReleaseAssets({
owner,
repo,
release_id: id,
})

const fileTemplates = [
{
name: `gcm-linux_amd64.${version}.tar.gz`,
platform: 'linux',
arch: 'amd64',
},
{
name: `gcm-osx-arm64-${version}.tar.gz`,
platform: 'darwin',
arch: 'arm64',
},
{
name: `gcm-osx-x64-${version}.tar.gz`,
platform: 'darwin',
arch: 'amd64',
},
]

const files = []

for (const ft of fileTemplates) {
const asset = assets.data.find(a => a.name === ft.name)

if (!asset) {
throw new Error(`Could not find asset for file: ${ft.name}`)
}

const url = asset.browser_download_url
console.log(`⏳ Fetching checksum for ${ft.name}`)
const checksum = await fetchAssetChecksum(url)
console.log(`🔑 ${checksum}`)
files.push({ ...ft, url, checksum })
}

updateGitCredentialManagerDependencies(version, files)

console.log(
`✅ Updated dependencies metadata to Git credential manager '${version}'`
)
return true
}

run().then(success => process.exit(success ? 0 : 1))
26 changes: 2 additions & 24 deletions script/update-git.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import path from 'path'
import crypto from 'crypto'
import ChildProcess from 'child_process'
import { Octokit, RestEndpointMethodTypes } from '@octokit/rest'
import semver from 'semver'
import { updateGitDependencies } from './lib/dependencies'
import yargs from 'yargs'
import fetch from 'node-fetch'
import { fetchAssetChecksum } from './fetch-asset-checksum'

process.on('unhandledRejection', reason => {
console.log(reason)
Expand Down Expand Up @@ -72,27 +71,6 @@ async function getLatestStableRelease() {
return latestTag.toString()
}

async function calculateAssetChecksum(uri: string) {
return new Promise<string>((resolve, reject) => {
const hs = crypto.createHash('sha256', { encoding: 'hex' })
hs.on('finish', () => resolve(hs.read()))

const headers: Record<string, string> = {
'User-Agent': 'dugite-native',
accept: 'application/octet-stream',
}

fetch(uri, { headers })
.then(x =>
x.ok
? Promise.resolve(x)
: Promise.reject(new Error(`Server responded with ${x.status}`))
)
.then(x => x.buffer())
.then(x => hs.end(x))
})
}

async function getPackageDetails(
assets: ReleaseAssets,
body: string,
Expand All @@ -119,7 +97,7 @@ async function getPackageDetails(
let checksum: string
if (match == null || match.length !== 2) {
console.log(`🔴 No checksum for ${archValue} in release notes body`)
checksum = await calculateAssetChecksum(minGitFile.browser_download_url)
checksum = await fetchAssetChecksum(minGitFile.browser_download_url)
console.log(`✅ Calculated checksum for ${archValue} from downloaded asset`)
} else {
console.log(`✅ Got checksum for ${archValue} from release notes body`)
Expand Down
Loading