Compare commits
163 Commits
Author | SHA1 | Date | |
---|---|---|---|
f110a678f5 | |||
bfcc41e678 | |||
917323e628 | |||
e0c7e2a725 | |||
|
7bc1195651 | ||
|
786c441206 | ||
|
558f12143c | ||
|
2cd8137eeb | ||
|
77f77c3e8b | ||
|
143637c4fc | ||
|
06bdaca2c1 | ||
|
10c0963c6d | ||
|
30c00bf385 | ||
|
d6b1a8d591 | ||
|
c090c23662 | ||
|
d8cd3257e0 | ||
|
93e9740904 | ||
|
95d31440db | ||
|
f916de4ff4 | ||
|
b3615798ac | ||
|
4f5e3068cc | ||
|
86dab14dfd | ||
|
fa0c7b9ac1 | ||
|
863aefcc9d | ||
|
d6ed51a6f0 | ||
|
efed3f3cc1 | ||
|
13a337a9b8 | ||
|
ac561c87a4 | ||
|
6f924bbb78 | ||
|
cb40378ce6 | ||
|
74f650bb33 | ||
|
b893475bf9 | ||
|
cfa76a1ae7 | ||
|
716be074d3 | ||
|
2249395b68 | ||
|
b7b967f078 | ||
|
df19db009c | ||
|
b789a373ac | ||
|
80ea5c8f2c | ||
|
aee24c13f3 | ||
|
d77c4fdfd4 | ||
|
21b99568fe | ||
|
0835da33bd | ||
|
c0b18d2f43 | ||
|
af2ea06031 | ||
|
eb36d5f680 | ||
|
e0f2b0031a | ||
|
59c7f9c4ce | ||
|
c26fc558a8 | ||
|
0b3a88b35a | ||
|
1da26533a1 | ||
|
702e7112e2 | ||
|
6a00c973fb | ||
|
a7ff547627 | ||
|
46233a24ae | ||
|
0741c67ed3 | ||
|
2d88efd6e2 | ||
|
2926b8c82d | ||
|
48eb74f956 | ||
|
021137402f | ||
|
4227e0fa09 | ||
|
f1101d51bc | ||
|
1e8aa06e8f | ||
|
7df140fdbb | ||
|
d3f5d490e6 | ||
|
2b75661fd2 | ||
|
bd262a8978 | ||
|
14e56223cd | ||
|
a8da58dd52 | ||
|
522b08f4fb | ||
|
1124d1661a | ||
|
7c3bb81709 | ||
|
3d32dbd623 | ||
|
e902f2afac | ||
|
0132417d3a | ||
|
2376e90494 | ||
|
af84310aa0 | ||
|
02c3f02a25 | ||
|
4661a20940 | ||
|
d1aba02e40 | ||
|
87f5690188 | ||
|
f9c717556d | ||
|
b7be07cd11 | ||
|
bccd87fe75 | ||
|
3855041754 | ||
|
72c147effd | ||
|
241f21c28b | ||
|
7035d63440 | ||
|
561e1dcfde | ||
|
04327b45b0 | ||
|
435be3b612 | ||
|
ef71b6110f | ||
|
4611d58702 | ||
|
6f0311f20f | ||
|
7b4d73a9db | ||
|
5144a4ebeb | ||
|
6d27d4d607 | ||
|
6349403466 | ||
|
9e6aad4060 | ||
|
3356fe58aa | ||
|
4bf2ae8436 | ||
|
a748f6afa7 | ||
|
d4fe53e46b | ||
|
879fa90155 | ||
|
912747b966 | ||
|
23a0258b4a | ||
|
2210711e57 | ||
|
1a1db12656 | ||
|
43287ec9cf | ||
|
4bc423721a | ||
|
5ef1917f61 | ||
|
3b98325435 | ||
|
7688e0cbc7 | ||
|
5595250e09 | ||
|
4e8f7f271f | ||
|
f2db146379 | ||
|
11e6e12f60 | ||
|
56827f467a | ||
|
34a05d36a6 | ||
|
bb1ee93cb9 | ||
|
de64657f2c | ||
|
32e0aac7fa | ||
|
d62945518b | ||
|
a73381dafa | ||
|
3c564909d0 | ||
|
e65ddbcdfd | ||
|
71f3728648 | ||
|
54b0888107 | ||
|
0a056599a3 | ||
|
18c361ce7f | ||
|
7240558fd8 | ||
|
d76304d5ea | ||
|
947625402d | ||
|
6285473aa7 | ||
|
0d7242e7fc | ||
|
28dd92bcec | ||
|
e0fff7d62e | ||
|
5171313fd6 | ||
|
9d6af11683 | ||
|
b99b892baf | ||
|
e3bf97c1ca | ||
|
5adc4e70a4 | ||
|
a01b7130b8 | ||
|
dbd20f76d5 | ||
|
df0a3488d5 | ||
|
5d1637699c | ||
|
767f48236c | ||
|
cd04389146 | ||
|
d48a659702 | ||
|
462132dc28 | ||
|
e6cfcc57fe | ||
|
9a7204dfca | ||
|
22751c3d2b | ||
|
a87c48b4ee | ||
|
64b17ac379 | ||
|
5c3f366371 | ||
|
c4b36f3e20 | ||
|
796c3370ca | ||
|
e9f7e6fd36 | ||
|
edcae1c219 | ||
|
bba2ce50bb | ||
|
e35659c99c | ||
|
598702c8b2 |
158
.github/workflows/assign-milestones.js
vendored
Normal file
158
.github/workflows/assign-milestones.js
vendored
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
// assign a milestone to issues or PRs added to a project, with a name corresponding
|
||||||
|
// to the name of the project - create the milestone if it does not exist
|
||||||
|
//
|
||||||
|
// adding a *second* project to the issue will update the milestone accordingly
|
||||||
|
// removing that project will reset the milestone entirely (not use the other project)
|
||||||
|
// and, no idea what happens if one very quickly adds and removes an issue
|
||||||
|
//
|
||||||
|
// an issue or PR actually becomes a card (or, a card is actually created...) when
|
||||||
|
// it's move to a project column for the first time - being assigned to the project
|
||||||
|
// and showing in project's backlog is not enough.
|
||||||
|
|
||||||
|
module.exports = async ({github, context, core}) => {
|
||||||
|
|
||||||
|
const restapi = github.rest
|
||||||
|
|
||||||
|
function last1(s) {
|
||||||
|
const pos = s.lastIndexOf('/')
|
||||||
|
return s.substring(pos + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function last2(s) {
|
||||||
|
const pos1 = s.lastIndexOf('/')
|
||||||
|
const pos2 = s.lastIndexOf('/', pos1-1)
|
||||||
|
return [ s.substring(pos2 + 1, pos1), s.substring(pos1 + 1) ]
|
||||||
|
}
|
||||||
|
|
||||||
|
function firstOrDefault(items, predicate) {
|
||||||
|
for (const item of items) {
|
||||||
|
if (predicate(item)) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// insanely enough, due to the total lack of documentation, this
|
||||||
|
// is the best way one can figure out what exactly we are getting
|
||||||
|
console.log(github)
|
||||||
|
console.log(context)
|
||||||
|
console.log(context.payload)
|
||||||
|
|
||||||
|
//console.log(`event: ${github.event_name}/${github.event.action}`)
|
||||||
|
|
||||||
|
// get and validate the event name
|
||||||
|
const eventName = context.eventName
|
||||||
|
if (eventName != 'project_card') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// get and validate the event action
|
||||||
|
const eventAction = context.payload.action
|
||||||
|
if (eventAction != 'created' && eventAction != 'deleted') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`event: ${eventName}/${eventAction}`)
|
||||||
|
|
||||||
|
const columnId = context.payload.project_card.column_id
|
||||||
|
const columnResponse = await restapi.projects.getColumn({
|
||||||
|
column_id: columnId
|
||||||
|
})
|
||||||
|
const column = columnResponse.data
|
||||||
|
console.log(column)
|
||||||
|
|
||||||
|
const projectId = last1(column.project_url)
|
||||||
|
const projectResponse = await restapi.projects.get({
|
||||||
|
project_id: projectId
|
||||||
|
});
|
||||||
|
const project = projectResponse.data
|
||||||
|
console.log(project)
|
||||||
|
const projectName = project.name
|
||||||
|
|
||||||
|
// -- when a card is deleted it cannot be fetched!
|
||||||
|
//const cardId = context.payload.project_card.id
|
||||||
|
//const cardResponse = await restapi.projects.getCard({
|
||||||
|
// card_id: cardId
|
||||||
|
//})
|
||||||
|
//const card = cardResponse.data
|
||||||
|
//console.log(card)
|
||||||
|
|
||||||
|
//const [ itemType, itemNumber ] = last2(card.content_url)
|
||||||
|
const [ itemType, itemNumber ] = last2(context.payload.project_card.content_url)
|
||||||
|
const isIssue = itemType == 'issues'
|
||||||
|
const isPull = itemType == 'pulls'
|
||||||
|
if (!isIssue && !isPull) {
|
||||||
|
core.setFailed(`Unsupported item type ${itemType}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const itemApi = isIssue ? restapi.issues : restapi.pulls
|
||||||
|
|
||||||
|
var request = {
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
}
|
||||||
|
request[isIssue ? 'issue_number' : 'pull_number'] = itemNumber
|
||||||
|
console.log(request)
|
||||||
|
|
||||||
|
const itemResponse = await itemApi.get(request)
|
||||||
|
const item = itemResponse.data
|
||||||
|
console.log(item)
|
||||||
|
const itemId = item.id
|
||||||
|
const itemMilestone = item.milestone
|
||||||
|
console.log(`item: ${itemType}/${itemId} milestone: ${itemMilestone == null ? '<none>' : itemMilestone}`)
|
||||||
|
|
||||||
|
if (eventAction == 'created') {
|
||||||
|
console.log('add or update milestone of issue/pull of created card')
|
||||||
|
|
||||||
|
const milestonesResponse = await restapi.issues.listMilestones({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
})
|
||||||
|
const milestones = milestonesResponse.data
|
||||||
|
console.log(milestones)
|
||||||
|
var milestone = firstOrDefault(milestones, (x) => x.title == projectName)
|
||||||
|
|
||||||
|
if (!milestone) {
|
||||||
|
console.log(`create milestone '${projectName}'`)
|
||||||
|
const milestoneResponse = await restapi.issues.createMilestone({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
title: projectName
|
||||||
|
})
|
||||||
|
milestone = milestoneResponse.data
|
||||||
|
}
|
||||||
|
|
||||||
|
const milestoneNumber = milestone.number
|
||||||
|
|
||||||
|
if (!item.milestone || item.milestone.number != milestoneNumber)
|
||||||
|
{
|
||||||
|
request = {
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
milestone: milestoneNumber
|
||||||
|
}
|
||||||
|
request[isIssue ? 'issue_number' : 'pull_number'] = itemNumber
|
||||||
|
await itemApi.update(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (eventAction == 'deleted') {
|
||||||
|
if (itemMilestone) {
|
||||||
|
console.log('remove milestone from issue/pull of deleted card')
|
||||||
|
request = {
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
}
|
||||||
|
request[isIssue ? 'issue_number' : 'pull_number'] = itemNumber
|
||||||
|
request.milestone = null
|
||||||
|
await itemApi.update(request)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log('deleted card had no milestone')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(`nothing to do for evet action ${eventAction}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
.github/workflows/assign-milestones.yml
vendored
Normal file
46
.github/workflows/assign-milestones.yml
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
name: Assign Milestones
|
||||||
|
on:
|
||||||
|
project_card:
|
||||||
|
# ignore: moved, converted, edited
|
||||||
|
types: [ created, deleted, moved ] # FIXME temp
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
assign:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Assign
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Assign
|
||||||
|
uses: actions/github-script@v5
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.MY_GITHUB_TOKEN_TESTREPO }}
|
||||||
|
script: |
|
||||||
|
|
||||||
|
// see https://github.com/actions/github-script
|
||||||
|
//
|
||||||
|
// note: 'github' below is not the same as the yml-level 'github' context
|
||||||
|
// see https://docs.github.com/en/actions/learn-github-actions/contexts
|
||||||
|
// for yml contexts
|
||||||
|
//
|
||||||
|
// github A pre-authenticated octokit/rest.js client with pagination plugins
|
||||||
|
// .rest The REST API (e.g. github.rest.issues.get(...) gets an issue)
|
||||||
|
// .request
|
||||||
|
// .paginate
|
||||||
|
// .graphql
|
||||||
|
// context An object containing the context of the workflow run
|
||||||
|
// see https://github.com/actions/toolkit/blob/main/packages/github/src/context.ts
|
||||||
|
// core A reference to the @actions/core package
|
||||||
|
// glob A reference to the @actions/glob package
|
||||||
|
// io A reference to the @actions/io package
|
||||||
|
// exec A reference to the @actions/exec package
|
||||||
|
// require A proxy wrapper around the normal Node.js require to enable requiring relative paths
|
||||||
|
// (relative to the current working directory) + requiring npm packages installed in the
|
||||||
|
// current working directory.
|
||||||
|
|
||||||
|
const script = require('./.github/workflows/assign-milestones.js')
|
||||||
|
await script({github, context, core})
|
137
.github/workflows/assign-to-project.yml
vendored
Normal file
137
.github/workflows/assign-to-project.yml
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
name: Assign PRs to Project
|
||||||
|
on:
|
||||||
|
#issues:
|
||||||
|
# types: [ opened ]
|
||||||
|
|
||||||
|
#pull_request:
|
||||||
|
# types: [ opened ]
|
||||||
|
|
||||||
|
# important to use pull_request_target here to run code from 'main' not the PR,
|
||||||
|
# with access to PAT - and safe permission to make changes to the project
|
||||||
|
pull_request_target:
|
||||||
|
types: [ opened, labeled ]
|
||||||
|
|
||||||
|
# github-script: https://github.com/actions/github-script
|
||||||
|
# -> points to github rest (octokit) reference doc
|
||||||
|
|
||||||
|
# github PAT: https://github.com/settings/tokens
|
||||||
|
# must have full repo access
|
||||||
|
|
||||||
|
# FIXME how can I prevent a user from creating a PR and stealing my token?
|
||||||
|
# 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
|
||||||
|
# curl -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ghp_..." https://api.github.com/projects/1/columns?owner=zpqrtbnk&repo=test-repo
|
||||||
|
# curl -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ghp_..." https://api.github.com/projects/1/columns?owner=zpqrtbnk-alt&repo=test-repo-alt
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
assign:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Assign
|
||||||
|
steps:
|
||||||
|
- name: Assign
|
||||||
|
uses: actions/github-script@v4
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.MY_GITHUB_TOKEN_TESTREPO }}
|
||||||
|
script: |
|
||||||
|
//const project_name = 'The API Team Board'
|
||||||
|
//const column_name = 'Drafting'
|
||||||
|
|
||||||
|
const project_name = 'test-project'
|
||||||
|
const column_name = 'To do'
|
||||||
|
|
||||||
|
function firstOrDefault(items, predicate) {
|
||||||
|
for (const item of items) {
|
||||||
|
if (predicate(item)) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the project
|
||||||
|
console.log('find project...')
|
||||||
|
const projects = await github.projects.listForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
})
|
||||||
|
console.log(`retrieved ${projects.data.length} projects.`)
|
||||||
|
const project = firstOrDefault(projects.data, (x) => x.name === project_name)
|
||||||
|
if (!project) {
|
||||||
|
core.setFailed(`Failed to find project "${project_name}".`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(`project '${project_name}' id: ${project.id}.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the column
|
||||||
|
console.log('find column...')
|
||||||
|
const columns = await github.projects.listColumns({
|
||||||
|
project_id: project.id
|
||||||
|
})
|
||||||
|
console.log(`retrieved ${columns.data.length} columns.`)
|
||||||
|
const column = firstOrDefault(columns.data, (x) => x.name === column_name)
|
||||||
|
if (!column) {
|
||||||
|
core.setFailed(`Failed to find column "${column_name}" in project ${project.name}.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(`column '${column_name}' id: ${column.id}.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine content type
|
||||||
|
console.log('determine content type...')
|
||||||
|
const event_name = context.eventName
|
||||||
|
var content_type = null
|
||||||
|
var item_number = null
|
||||||
|
var item_id = null
|
||||||
|
if (event_name === 'issues') {
|
||||||
|
content_type = 'Issue'
|
||||||
|
// temp!
|
||||||
|
core.setFailed(`Unsupported: issue.`)
|
||||||
|
return
|
||||||
|
item_number = context.issue.number
|
||||||
|
item_id = context.issue.id
|
||||||
|
}
|
||||||
|
if (event_name === 'pull_request' || event_name === 'pull_request_target') {
|
||||||
|
content_type = 'PullRequest'
|
||||||
|
item_number = context.payload.pull_request.number
|
||||||
|
item_id = context.payload.pull_request.id
|
||||||
|
}
|
||||||
|
if (!content_type) {
|
||||||
|
core.setFailed(`Unexpected event name "${event_name}".`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(`content type: ${content_type}.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the item
|
||||||
|
console.log('get the item...')
|
||||||
|
const item = await github.issues.get({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: item_number
|
||||||
|
})
|
||||||
|
if (!item) {
|
||||||
|
core.setFailed(`Failed to get item ${item_number}.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(`${content_type} #${context.issue.number} id: ${item.data.id}.`)
|
||||||
|
if (item_id === item.data.id) {
|
||||||
|
console.log(`item_id: ${item_id}`)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log(`but 'context.payload' provides item_id: ${item_id} and meh?`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('create the card...')
|
||||||
|
console.log(`in column ${column.id} for item ${item_id} of type ${content_type}`)
|
||||||
|
await github.projects.createCard({
|
||||||
|
column_id: column.id,
|
||||||
|
//note:,
|
||||||
|
content_id: item_id,
|
||||||
|
content_type: content_type
|
||||||
|
})
|
||||||
|
console.log('created')
|
137
.github/workflows/publish-release.js
vendored
Normal file
137
.github/workflows/publish-release.js
vendored
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
module.exports = /*async*/ ({github, context, core}) => {
|
||||||
|
|
||||||
|
const restapi = github.rest
|
||||||
|
var dryrun = context.payload.inputs.dryrun
|
||||||
|
|
||||||
|
function firstOrDefault(items, predicate) {
|
||||||
|
for (const item of items) {
|
||||||
|
if (predicate(item)) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
async function validateRelease() {
|
||||||
|
|
||||||
|
const version = context.payload.inputs.version
|
||||||
|
const tag = "v" + version
|
||||||
|
console.log(`Validate version '${version}'.`)
|
||||||
|
|
||||||
|
// git branch must exist
|
||||||
|
const branchRefs = await restapi.git.listMatchingRefs({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
ref: `heads/release/${version}`
|
||||||
|
})
|
||||||
|
if (firstOrDefault(branchRefs.data, (x) => x.ref == `refs/heads/release/${version}`) == null) {
|
||||||
|
core.setFailed(`Could not find branch 'release/${version}'.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`Found branch 'release/${version}'.`)
|
||||||
|
|
||||||
|
// github milestone must exist and be open
|
||||||
|
const milestone = await getMilestone()
|
||||||
|
if (milestone == null) {
|
||||||
|
core.setFailed(`Could not find milestone '${version}'.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (milestone.state != "open") {
|
||||||
|
core.setFailed(`Milestone '${version}' is already closed.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`Found open milestone '${version}'.`)
|
||||||
|
|
||||||
|
// github release must exist and not be published yet
|
||||||
|
const release = await getRelease()
|
||||||
|
if (release === null) {
|
||||||
|
core.setFailed(`Could not find a GitHub release for tag '${tag}'.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!release.draft) {
|
||||||
|
core.setFailed(`GitHub release for tag '${tag}' is already published.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`Found yet-unpublished GitHub release for tag '${tag}'.`)
|
||||||
|
|
||||||
|
// tag must not exist
|
||||||
|
const tagRefs = await restapi.git.listMatchingRefs({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
ref: `tags/${tag}`
|
||||||
|
})
|
||||||
|
if (firstOrDefault(tagRefs.data, (x) => x.ref == `tags/${tag}`) != null) {
|
||||||
|
core.setFailed(`Tag '${tag}' already exists.`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log(`Verified that tag '${tag}' does not exist yet.`)
|
||||||
|
|
||||||
|
console.log('Release is valid.')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function publishRelease() {
|
||||||
|
|
||||||
|
const version = context.payload.inputs.version
|
||||||
|
const tag = "v" + version
|
||||||
|
console.log(`Publish GitHub release '${version}'.`)
|
||||||
|
|
||||||
|
const release = await getRelease()
|
||||||
|
|
||||||
|
await restapi.repos.updateRelease({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
release_id: release.id,
|
||||||
|
draft: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function closeMilestone() {
|
||||||
|
|
||||||
|
const version = context.payload.inputs.version
|
||||||
|
const tag = "v" + version
|
||||||
|
console.log(`Close milestone '${version}'.`)
|
||||||
|
|
||||||
|
const milestone = await getMilestone()
|
||||||
|
await restapi.issues.updateMilestone({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
milestone_number: milestone.number,
|
||||||
|
state: "closed"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getRelease() {
|
||||||
|
|
||||||
|
// note: getReleaseByTag only returns published releases
|
||||||
|
|
||||||
|
// note: we may eventually need to paginate
|
||||||
|
// and then releases.headers should contain what we need?
|
||||||
|
// https://octokit.github.io/rest.js/v18#pagination
|
||||||
|
|
||||||
|
const version = context.payload.inputs.version
|
||||||
|
const tag = `v${version}`
|
||||||
|
const releases = await restapi.repos.listReleases({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
})
|
||||||
|
const release = firstOrDefault(releases.data, (x) => x.tag_name == tag)
|
||||||
|
return release
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getMilestone() {
|
||||||
|
|
||||||
|
const version = context.payload.inputs.version
|
||||||
|
const milestonesResponse = await restapi.issues.listMilestones({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo
|
||||||
|
})
|
||||||
|
const milestones = milestonesResponse.data
|
||||||
|
return firstOrDefault(milestones, (x) => x.title == version)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
validateRelease: validateRelease,
|
||||||
|
publishRelease: publishRelease,
|
||||||
|
closeMilestone: closeMilestone
|
||||||
|
}
|
||||||
|
}
|
46
.github/workflows/publish-release.yml
vendored
Normal file
46
.github/workflows/publish-release.yml
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
name: Publish Release
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'Version'
|
||||||
|
required: true
|
||||||
|
dryrun:
|
||||||
|
description: 'DryRun'
|
||||||
|
required: true
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
job:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Configure repository
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git config user.email "github-actions@hazelcast.com"
|
||||||
|
git config user.name "GitHub Actions (Build Release)"
|
||||||
|
|
||||||
|
- name: Validate the release
|
||||||
|
uses: actions/github-script@v5
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const scriptf = require('./.github/workflows/publish-release.js')
|
||||||
|
const script = scriptf({github, context, core})
|
||||||
|
await script.validateRelease()
|
||||||
|
|
||||||
|
- name: Finalize GitHub release and milestone
|
||||||
|
if: ${{ github.event.inputs.dryrun == 'false' }}
|
||||||
|
uses: actions/github-script@v5
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const scriptf = require('./.github/workflows/publish-release.js')
|
||||||
|
const script = scriptf({github, context, core})
|
||||||
|
await script.publishRelease()
|
||||||
|
await script.closeMilestone()
|
26
.github/workflows/rest-description.yml
vendored
Normal file
26
.github/workflows/rest-description.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
name: Toy with issue description
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: labeled
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
toy-desc:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: |
|
||||||
|
!contains(github.event.issue.title, '!exclude!') ||
|
||||||
|
contains(github.event.issue.title, '!force!')
|
||||||
|
steps:
|
||||||
|
- name: Toy with issue description
|
||||||
|
uses: actions/github-script@v4.0.2
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const title = `${{ github.event.issue.title }} !`
|
||||||
|
const body = `updated\n${{ github.event.issue.body }}`
|
||||||
|
github.issues.update({
|
||||||
|
issue_number: context.issue.number,
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
title: title,
|
||||||
|
body: body
|
||||||
|
})
|
||||||
|
|
82
.github/workflows/symlink-test.yml
vendored
Normal file
82
.github/workflows/symlink-test.yml
vendored
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
name: Symlink Test
|
||||||
|
on:
|
||||||
|
# trigger on push to any branch
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'release/*'
|
||||||
|
tags-ignore:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
|
||||||
|
# try to create and push the symlink
|
||||||
|
symlink-test:
|
||||||
|
|
||||||
|
name: Symlink Test
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
# checkout the code
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# symlink via bash
|
||||||
|
# this does *not* create a symlink, but a directory
|
||||||
|
#- name: Symlink Bash
|
||||||
|
# shell: bash
|
||||||
|
# run: |
|
||||||
|
# if ! [ -L bang ]; then
|
||||||
|
# ln -s duh bang
|
||||||
|
# ls -l
|
||||||
|
# git config --global user.email "stephan@REDACTED.com"
|
||||||
|
# git config --global user.name "Stephan"
|
||||||
|
# git config --global core.symlinks "true"
|
||||||
|
# git add bang
|
||||||
|
# git commit -m "created symlink"
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# symlink via pwsh
|
||||||
|
# this creates a 'bang' file that contains 'duh'
|
||||||
|
# on local machine, it fails 'New-Item: Administrator privilege required for this operation.'
|
||||||
|
#
|
||||||
|
# update: it creates *something* that is listed as a directory in the log,
|
||||||
|
# and that GitHub represents as a link, so it has to be a link, but when
|
||||||
|
# I check the thing out, it's a file
|
||||||
|
# because Windows won't create the link but on Linux, it's checked out as a link
|
||||||
|
#
|
||||||
|
#- name: Symlink Pwsh
|
||||||
|
# shell: pwsh
|
||||||
|
# run: |
|
||||||
|
# if (! (test-path bang)) {
|
||||||
|
# New-Item -ItemType SymbolicLink -Name bang -Target duh
|
||||||
|
# write-output "DIR:"
|
||||||
|
# ls .
|
||||||
|
# write-output "DIR:"
|
||||||
|
# ls bang
|
||||||
|
# git config --global user.email "stephan@REDACTED.com"
|
||||||
|
# git config --global user.name "Stephan"
|
||||||
|
# git config --global core.symlinks "true"
|
||||||
|
# git add bang
|
||||||
|
# git commit -m "created symlink"
|
||||||
|
# }
|
||||||
|
|
||||||
|
# see
|
||||||
|
# this just creates the symlink in Git - works on Windows
|
||||||
|
# BUT will be checked out as a file and we don't care
|
||||||
|
- name: Symlink Git
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if ! [ -f "bang" ]; then
|
||||||
|
git update-index --add --cacheinfo 120000 "$(echo "duh" | git hash-object -w --stdin)" "bang"
|
||||||
|
git config --global user.email "stephan@REDACTED.com"
|
||||||
|
git config --global user.name "Stephan"
|
||||||
|
git commit -m "created symlink"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# push changes back
|
||||||
|
- name: Push
|
||||||
|
shell: bash
|
||||||
|
run: git push
|
25
.github/workflows/test-push.yml
vendored
Normal file
25
.github/workflows/test-push.yml
vendored
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
name: Test Push
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
foo:
|
||||||
|
name: Foo
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: ${{github.ref}}
|
||||||
|
|
||||||
|
- name: Foo
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "foo" >> foo.txt
|
||||||
|
|
||||||
|
- name: Push
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git config --global user.name "GitHub Actions"
|
||||||
|
git config --global user.email "github-actions@hazelcast.com"
|
||||||
|
git add foo.txt
|
||||||
|
git commit -m "Foo"
|
||||||
|
git push
|
27
README.md
27
README.md
|
@ -1,19 +1,30 @@
|
||||||
# test-repo
|
# A Git(Hub) Test Repository
|
||||||
|
|
||||||
A Git(Hub) Test Repository
|
Hey! This is my personal Git(Hub) Test Repository where I experiment with Git and GitHub.
|
||||||
|
|
||||||
`git clone https://github.com/zpqrtbnk/test-repo.git .`
|
If you are new to Git and GitHub and found this repository through Google: feel free to clone the repository and experiment with it! You will not be able to push back to the repository, as it is *my* repository and I cannot let everybody push to it. The right way to do it on GitHub is:
|
||||||
|
|
||||||
We have pages at: http://zpqrtbnk.github.io/test-repo/
|
1. fork the repository in your own account,
|
||||||
|
2. make changes and push them in a branch of your own fork,
|
||||||
|
3. create a Pull Request in my repository.
|
||||||
|
|
||||||
We have an image in the README
|
I will get notified, will review the changes that you propose, and eventually will either merge the changes, or reject them. This *may* take some time as I am not actively monitoring nor maintaining this repository, as you can guess, but I try to be helpful ;)
|
||||||
![Image](https://raw.github.com/zpqrtbnk/test-repo/master/wtf.jpg)
|
|
||||||
|
|
||||||
etc
|
Don't expect to find anything meaningful nor useful in the repository. Also, I happen to force-push a reset of everything from time to time. This means that I reset all history, including changes that you may have submitted. In theory, noone ever does this to a repository. But hey, this is a *test* repository after all.
|
||||||
etc
|
|
||||||
|
|
||||||
|
The rest of this README file is mostly random stuff.
|
||||||
|
|
||||||
|
Clone the repository with: `git clone https://github.com/zpqrtbnk/test-repo.git .`
|
||||||
|
|
||||||
|
We have test GitHUb pages (from the `gh-pages` branch) at: http://zpqrtbnk.github.io/test-repo/
|
||||||
|
|
||||||
|
We have an image in the README (markdown)
|
||||||
|
![Image](wtf.jpg)
|
||||||
|
|
||||||
|
We have an image in the README (html)
|
||||||
<img src="./wtf.jpg" />
|
<img src="./wtf.jpg" />
|
||||||
|
|
||||||
|
We have an image in the README (more html)
|
||||||
<p align="center" style="background:#000;padding:5px;color:#fff;font-size:150%;margin-bottom:64px">
|
<p align="center" style="background:#000;padding:5px;color:#fff;font-size:150%;margin-bottom:64px">
|
||||||
<img src="./wtf.jpg" />
|
<img src="./wtf.jpg" />
|
||||||
<span style="margin-left:48px;">wubble</span>
|
<span style="margin-left:48px;">wubble</span>
|
||||||
|
|
1
duh/bah.txt
Normal file
1
duh/bah.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
bah
|
1
duh/duh.txt
Normal file
1
duh/duh.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
duh
|
Loading…
Reference in New Issue
Block a user