Skip to content

Commit 558376b

Browse files
committed
Updates to copy-release action
1 parent 49f4003 commit 558376b

8 files changed

Lines changed: 165 additions & 125 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

.github/actions/copy-release-to-another-repo/README.md

Lines changed: 0 additions & 20 deletions
This file was deleted.

.github/actions/copy-release-to-another-repo/lib/index.js

Lines changed: 73 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/actions/copy-release-to-another-repo/package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.github/actions/copy-release-to-another-repo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{
2-
"main": "index.js",
32
"license": "ISC",
43
"scripts": {
54
"build": "rm -rf lib && ncc build -s src/index.ts -o lib"
@@ -10,6 +9,7 @@
109
"node-fetch": "^2.6.0"
1110
},
1211
"devDependencies": {
12+
"@types/node-fetch": "^2.5.3",
1313
"@zeit/ncc": "^0.20.5"
1414
},
1515
"prettier": {

.github/actions/copy-release-to-another-repo/src/index.ts

Lines changed: 69 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,122 +1,138 @@
1-
const core = require('@actions/core')
2-
const github = require('@actions/github')
3-
const fs = require('fs')
4-
const path = require('path')
5-
const fetch = require('node-fetch')
1+
import {getInput, setOutput, setFailed} from '@actions/core'
2+
import {context, GitHub} from '@actions/github'
3+
import * as fs from 'fs'
4+
import * as path from 'path'
5+
import fetch from 'node-fetch'
6+
import { ReposCreateReleaseResponse, ReposGetReleaseByTagResponse } from '@octokit/rest'
67

78
const GITHUB_TOKEN = getEnvVar('GITHUB_TOKEN')
89
const UPLOAD_GITHUB_TOKEN = getEnvVar('UPLOAD_GITHUB_TOKEN')
9-
const INPUT_UPLOAD_OWNER_NAME = getEnvVar('INPUT_UPLOAD_OWNER_NAME')
10-
const INPUT_UPLOAD_REPO_NAME = getEnvVar('INPUT_UPLOAD_REPO_NAME')
1110

1211
process.on('unhandledRejection', (reason: any, _: Promise<any>) =>
1312
handleError(reason)
1413
)
1514
main().catch(handleError)
1615

1716
async function main() {
18-
const nwo = getEnvVar('GITHUB_REPOSITORY')
19-
const [owner, repo] = nwo.split('/')
17+
// Get the release from the current repository
18+
const tag = context.ref.replace('refs/tags/', '')
19+
const release = await getRelease(context.repo.owner, context.repo.repo, tag)
2020

21+
// Create a new release in another repository
22+
const [targetOwner, targetRepo] = getInput('target-repo').split('/')
23+
let publicRelease: ReposCreateReleaseResponse | ReposCreateReleaseResponse
2124
try {
22-
// Get the release from the current repository
23-
const release = await getRelease(owner, repo)
24-
const asset = release.assets.find((a: any) => {
25-
return a.name.match(/_darwin_amd64.tar.gz/i)
26-
})
27-
const filePath = await downloadAsset(asset)
25+
publicRelease = await getRelease(targetOwner, targetRepo, tag)
26+
} catch (error) {
27+
if (error.status && error.status == 404) {
28+
publicRelease = await createRelease(targetOwner, targetRepo, release)
29+
} else {
30+
throw error
31+
}
32+
}
2833

29-
// Create a new release in another repository
30-
const publicRelease = await createRelease(release)
34+
for (const asset of release.assets) {
35+
if (!(asset.name.match(/macOS/) || asset.name.match(/darwin/)) && !asset.name.match(/linux/)) {
36+
continue
37+
}
38+
const filePath = await downloadAsset(asset)
39+
for (const existingAsset of publicRelease.assets) {
40+
if (existingAsset.name == asset.name) {
41+
await deleteAsset(targetOwner, targetRepo, existingAsset)
42+
}
43+
}
3144
const assetUrl = await uploadAsset(publicRelease, filePath)
32-
core.setOutput('asset-url', assetUrl)
33-
} catch (error) {
34-
handleError(error)
45+
if (asset.name.match(/macOS/) || asset.name.match(/darwin/)) {
46+
setOutput('asset-url', assetUrl)
47+
}
3548
}
3649
}
3750

38-
async function getRelease(owner: string, repo: string) {
39-
const octokit = new github.GitHub(GITHUB_TOKEN)
40-
const tag = getEnvVar('GITHUB_REF').replace(/refs\/tags\//, '')
51+
async function getRelease(owner: string, repo: string, tag: string) {
52+
const octokit = new GitHub(GITHUB_TOKEN)
4153
const response = await octokit.repos.getReleaseByTag({ owner, repo, tag })
42-
checkResponse(response)
4354
return response.data
4455
}
4556

46-
async function createRelease(release: any) {
47-
const octokit = new github.GitHub(UPLOAD_GITHUB_TOKEN)
48-
57+
async function createRelease(owner: string, repo: string, release: ReposGetReleaseByTagResponse) {
58+
const octokit = new GitHub(UPLOAD_GITHUB_TOKEN)
4959
const response = await octokit.repos.createRelease({
50-
owner: INPUT_UPLOAD_OWNER_NAME,
51-
repo: INPUT_UPLOAD_REPO_NAME,
60+
owner,
61+
repo,
5262
tag_name: release.tag_name,
5363
name: release.name,
5464
body: release.body,
55-
target_commish: release.target_commish,
65+
target_commitish: release.target_commitish,
5666
prerelease: release.prerelease,
5767
draft: false,
5868
})
59-
checkResponse(response)
6069
return response.data
6170
}
6271

63-
async function uploadAsset(release: any, filePath: string) {
64-
const octokit = new github.GitHub(UPLOAD_GITHUB_TOKEN)
72+
async function uploadAsset(release: ReposGetReleaseByTagResponse | ReposCreateReleaseResponse, filePath: string) {
73+
const octokit = new GitHub(UPLOAD_GITHUB_TOKEN)
6574
const response = await octokit.repos.uploadReleaseAsset({
6675
url: release.upload_url,
6776
file: fs.readFileSync(filePath),
6877
name: path.basename(filePath),
6978
headers: {
70-
'content-type': 'application/gzip',
79+
'content-type': 'application/octet-stream',
7180
'content-length': fs.statSync(filePath).size,
7281
},
7382
})
74-
checkResponse(response)
75-
return response.data.browser_download_url
83+
// this seems like a bug in Rest.js types
84+
const url: string = (<any>response.data).browser_download_url
85+
return url
86+
}
87+
88+
interface Asset {
89+
id: number;
90+
url: string;
91+
name: string;
7692
}
7793

78-
async function downloadAsset(asset: any) {
79-
const options = {
94+
async function deleteAsset(owner: string, repo: string, asset: Asset) {
95+
const octokit = new GitHub(UPLOAD_GITHUB_TOKEN)
96+
await octokit.repos.deleteReleaseAsset({
97+
owner,
98+
repo,
99+
asset_id: asset.id
100+
})
101+
}
102+
103+
async function downloadAsset(asset: Asset) {
104+
let response = await fetch(asset.url, {
80105
redirect: 'manual',
81106
headers: {
82107
Authorization: `token ${GITHUB_TOKEN}`,
83108
Accept: 'application/octet-stream',
84109
},
85-
}
110+
})
86111

87-
let response = await fetch(asset.url, options)
88112
// Why didn't I just let fetch handle the redirect? Because that will
89113
// will forwarded the Authorization header to S3 and AWS doesn't like that.
90-
// For more deatails check out https://github.com/octokit/rest.js/issues/967
114+
// For more details check out https://github.com/octokit/rest.js/issues/967
91115
if (response.status === 302) {
92-
response = await fetch(response.headers.get('location'), {
116+
response = await fetch(response.headers.get('location') || '', {
93117
headers: { Accept: 'application/octet-stream' },
94118
})
95119
}
96120

97121
if (response.status === 200) {
98122
const data = await response.buffer()
99123
fs.writeFileSync(asset.name, data)
100-
return asset.name
101124
} else {
102125
throw new Error('failed to download asset: ' + (await response.text()))
103126
}
127+
return asset.name
104128
}
105129

106130
async function handleError(err: Error) {
107131
console.error(err)
108-
core.setFailed(err.message)
109-
}
110-
111-
function checkResponse(response: any) {
112-
if (response.status >= 200 || response.status < 300) return
113-
114-
throw new Error(
115-
`Failed to run ${response.request.url}. Errors: ${response.errors}`
116-
)
132+
setFailed(err.message)
117133
}
118134

119-
function getEnvVar(name: string) {
135+
function getEnvVar(name: string): string {
120136
const envVar = process.env[name]
121137
if (!envVar) {
122138
throw new Error(`env var named "${name} is not set"`)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
set -e
2+
3+
TOKEN="$(awk '/oauth_token/ {print $2}' ~/.config/hub | head -1)"
4+
5+
env \
6+
"GITHUB_REPOSITORY=github/gh-cli" \
7+
"GITHUB_REF=refs/tags/v0.0.195" \
8+
"INPUT_TARGET-REPO=github/homebrew-gh" \
9+
"GITHUB_TOKEN=$TOKEN" \
10+
"UPLOAD_GITHUB_TOKEN=$TOKEN" \
11+
node lib/index.js

.github/workflows/releases.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ jobs:
2727
id: copy
2828
uses: ./.github/actions/copy-release-to-another-repo
2929
with:
30-
UPLOAD_OWNER_NAME: github
31-
UPLOAD_REPO_NAME: homebrew-gh
30+
target-repo: github/homebrew-gh
3231
env:
3332
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
3433
UPLOAD_GITHUB_TOKEN: ${{secrets.UPLOAD_GITHUB_TOKEN}}

0 commit comments

Comments
 (0)