mirror of
https://gitea.com/actions/gitea-release-action.git
synced 2026-03-24 21:58:23 +00:00
Compare commits
16 Commits
v1.3.1
...
b8d9144f30
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8d9144f30 | ||
|
|
e476391eee | ||
|
|
fd3cba014c | ||
|
|
9ee2a5d4a3 | ||
|
|
4875285c09 | ||
|
|
aae35ac409 | ||
|
|
c95a2785f0 | ||
|
|
424dc33baa | ||
|
|
9ca8dcac95 | ||
|
|
05b1004877 | ||
|
|
008a54b0cd | ||
|
|
fe8e032280 | ||
|
|
3dbdc45d61 | ||
|
|
f66c1c98f1 | ||
|
|
65a502e85c | ||
|
|
f119011bd6 |
22
.devcontainer/devcontainer.json
Normal file
22
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,22 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/javascript-node
|
||||
{
|
||||
"name": "gitea-release-action",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"image": "mcr.microsoft.com/devcontainers/javascript-node:4-22-bookworm"
|
||||
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "yarn install",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
// "customizations": {},
|
||||
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
An action to support publishing release to Gitea.
|
||||
|
||||
Preserves the fields body, prerelease and name when pushing the release if no value is given.
|
||||
|
||||
## Inputs
|
||||
|
||||
The following are optional as `step.with` keys
|
||||
|
||||
10
action.yml
10
action.yml
@@ -10,10 +10,14 @@ inputs:
|
||||
body:
|
||||
description: "Note-worthy description of changes in release"
|
||||
required: false
|
||||
default: ${{ github.event.release.body != '' && github.event.release.body || null }}
|
||||
body_path:
|
||||
description: "Path to load description of changes in this release"
|
||||
required: false
|
||||
name:
|
||||
description: "Gives the release a custom name. Defaults to tag name"
|
||||
required: false
|
||||
default: ${{ github.ref_name }}
|
||||
default: ${{ github.event.release.name != '' && github.event.release.name || github.ref_name }}
|
||||
tag_name:
|
||||
description: "Gives a tag name. Defaults to github.GITHUB_REF"
|
||||
required: false
|
||||
@@ -21,9 +25,11 @@ inputs:
|
||||
draft:
|
||||
description: "Creates a draft release. Defaults to false"
|
||||
required: false
|
||||
default: ${{ github.event.release.draft || false }}
|
||||
prerelease:
|
||||
description: "Identify the release as a prerelease. Defaults to false"
|
||||
required: false
|
||||
default: ${{ github.event.release.prerelease || false }}
|
||||
files:
|
||||
description: "Newline-delimited list of path globs for asset files to upload"
|
||||
required: false
|
||||
@@ -49,4 +55,4 @@ runs:
|
||||
main: "dist/index.js"
|
||||
branding:
|
||||
color: "green"
|
||||
icon: "package"
|
||||
icon: "package"
|
||||
|
||||
149
dist/index.js
vendored
149
dist/index.js
vendored
@@ -40594,6 +40594,8 @@ var __webpack_exports__ = {};
|
||||
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
||||
(() => {
|
||||
|
||||
;// CONCATENATED MODULE: external "node:fs/promises"
|
||||
const promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:fs/promises");
|
||||
// EXTERNAL MODULE: external "fs"
|
||||
var external_fs_ = __nccwpck_require__(7147);
|
||||
var external_fs_namespaceObject = /*#__PURE__*/__nccwpck_require__.t(external_fs_, 2);
|
||||
@@ -43826,7 +43828,7 @@ var external_path_ = __nccwpck_require__(1017);
|
||||
// EXTERNAL MODULE: external "url"
|
||||
var external_url_ = __nccwpck_require__(7310);
|
||||
;// CONCATENATED MODULE: external "fs/promises"
|
||||
const promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("fs/promises");
|
||||
const external_fs_promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("fs/promises");
|
||||
// EXTERNAL MODULE: external "events"
|
||||
var external_events_ = __nccwpck_require__(2361);
|
||||
// EXTERNAL MODULE: external "stream"
|
||||
@@ -44870,10 +44872,10 @@ const defaultFS = {
|
||||
readlinkSync: external_fs_.readlinkSync,
|
||||
realpathSync,
|
||||
promises: {
|
||||
lstat: promises_namespaceObject.lstat,
|
||||
readdir: promises_namespaceObject.readdir,
|
||||
readlink: promises_namespaceObject.readlink,
|
||||
realpath: promises_namespaceObject.realpath,
|
||||
lstat: external_fs_promises_namespaceObject.lstat,
|
||||
readdir: external_fs_promises_namespaceObject.readdir,
|
||||
readlink: external_fs_promises_namespaceObject.readlink,
|
||||
realpath: external_fs_promises_namespaceObject.realpath,
|
||||
},
|
||||
};
|
||||
// if they just gave us require('fs') then use our default
|
||||
@@ -48145,20 +48147,25 @@ var crypto_js = __nccwpck_require__(4134);
|
||||
|
||||
|
||||
|
||||
function getIsTrue(v) {
|
||||
const trueValue = ['true', 'True', 'TRUE']
|
||||
return trueValue.includes(v)
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const server_url = core.getInput("server_url")
|
||||
const name = core.getInput("name")
|
||||
const body = getReleaseBody(core.getInput("body"), core.getInput("body_path"))
|
||||
const tag_name = core.getInput("tag_name")
|
||||
const draft = core.getInput("draft") === 'true'
|
||||
const prerelease = core.getInput("prerelease") === 'true'
|
||||
const draft = getIsTrue(core.getInput("draft"))
|
||||
const prerelease = getIsTrue(core.getInput("prerelease"))
|
||||
const files = core.getInput("files")
|
||||
const repository = core.getInput("repository")
|
||||
const token = core.getInput("token")
|
||||
const target_commitish = core.getInput("target_commitish")
|
||||
const md5sum = core.getInput("md5sum")
|
||||
const sha256sum = core.getInput("sha256sum")
|
||||
const md5sum = getIsTrue(core.getInput("md5sum"))
|
||||
const sha256sum = getIsTrue(core.getInput("sha256sum"))
|
||||
|
||||
const [owner, repo] = (repository).split("/")
|
||||
|
||||
@@ -48258,6 +48265,68 @@ function paths(patterns) {
|
||||
}, []);
|
||||
};
|
||||
|
||||
async function createStreamableFile(fpath) {
|
||||
const name = external_path_.basename(fpath);
|
||||
const handle = await promises_namespaceObject.open(fpath);
|
||||
const { size } = await handle.stat();
|
||||
|
||||
const file = new external_buffer_.File([], name);
|
||||
file.stream = () => handle.readableWebStream();
|
||||
file.close = async () => await handle?.close();
|
||||
|
||||
// Set correct size otherwise, fetch will encounter UND_ERR_REQ_CONTENT_LENGTH_MISMATCH
|
||||
Object.defineProperty(file, 'size', { get: () => size });
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
async function calculateMultipleHashes(file, algorithms = ['md5', 'sha256']) {
|
||||
const stream = file.stream();
|
||||
const reader = stream.getReader();
|
||||
|
||||
const hashers = algorithms.map(alg => {
|
||||
switch(alg.toLowerCase()) {
|
||||
case 'md5':
|
||||
return { name: 'md5', instance: crypto_js.algo.MD5.create() };
|
||||
case 'sha1':
|
||||
return { name: 'sha1', instance: crypto_js.algo.SHA1.create() };
|
||||
case 'sha256':
|
||||
return { name: 'sha256', instance: crypto_js.algo.SHA256.create() };
|
||||
case 'sha512':
|
||||
return { name: 'sha512', instance: crypto_js.algo.SHA512.create() };
|
||||
default:
|
||||
throw new Error(`not support hash: ${alg}`);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
const wordArray = crypto_js.lib.WordArray.create(value);
|
||||
|
||||
hashers.forEach(hasher => {
|
||||
hasher.instance.update(wordArray);
|
||||
});
|
||||
}
|
||||
|
||||
const result = {};
|
||||
hashers.forEach(hasher => {
|
||||
result[hasher.name] = hasher.instance.finalize().toString(crypto_js.enc.Hex);
|
||||
});
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {gitea.GiteaApi} client
|
||||
@@ -48274,32 +48343,55 @@ async function uploadFiles(client, owner, repo, release_id, all_files, params) {
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
})
|
||||
// deleted old release attachment
|
||||
const will_deleted = new Set();
|
||||
for (const filepath of all_files) {
|
||||
for (const attachment of attachments) {
|
||||
let will_deleted = [external_path_.basename(filepath), `${external_path_.basename(filepath)}.md5`, `${external_path_.basename(filepath)}.sha256`]
|
||||
if (will_deleted.includes(attachment.name)) {
|
||||
await client.repository.repoDeleteReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
attachmentId: attachment.id,
|
||||
})
|
||||
console.log(`Successfully deleted old release attachment ${attachment.name}`)
|
||||
}
|
||||
will_deleted.add(external_path_.basename(filepath));
|
||||
if (params.md5sum) {
|
||||
will_deleted.add(`${external_path_.basename(filepath)}.md5`);
|
||||
}
|
||||
const content = external_fs_.readFileSync(filepath);
|
||||
let blob = new external_buffer_.Blob([content]);
|
||||
if (params.sha256sum) {
|
||||
will_deleted.add(`${external_path_.basename(filepath)}.sha256`);
|
||||
}
|
||||
}
|
||||
for (const attachment of attachments) {
|
||||
if (will_deleted.has(attachment.name)) {
|
||||
await client.repository.repoDeleteReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
attachmentId: attachment.id,
|
||||
})
|
||||
console.log(`Successfully deleted old release attachment ${attachment.name}`)
|
||||
}
|
||||
}
|
||||
// upload new release attachment
|
||||
for (const filepath of all_files) {
|
||||
let curfile = await createStreamableFile(filepath)
|
||||
await client.repository.repoCreateReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
attachment: blob,
|
||||
attachment: curfile,
|
||||
name: external_path_.basename(filepath),
|
||||
})
|
||||
await curfile.close();
|
||||
let algorithms = [];
|
||||
if (params.md5sum) {
|
||||
let wordArray = crypto_js.lib.WordArray.create(content);
|
||||
let hash = crypto_js.MD5(wordArray).toString();
|
||||
blob = new external_buffer_.Blob([hash], { type : 'plain/text' });
|
||||
algorithms = algorithms.concat('md5');
|
||||
}
|
||||
if (params.sha256sum) {
|
||||
algorithms = algorithms.concat('sha256');
|
||||
}
|
||||
let hashes = {};
|
||||
if (algorithms.length !== 0) {
|
||||
curfile = await createStreamableFile(filepath)
|
||||
hashes = await calculateMultipleHashes(curfile, algorithms)
|
||||
await curfile.close();
|
||||
}
|
||||
if (params.md5sum) {
|
||||
let hash = hashes.md5;
|
||||
let blob = new external_buffer_.Blob([hash], { type : 'plain/text' });
|
||||
await client.repository.repoCreateReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
@@ -48309,9 +48401,8 @@ async function uploadFiles(client, owner, repo, release_id, all_files, params) {
|
||||
})
|
||||
}
|
||||
if (params.sha256sum) {
|
||||
let wordArray = crypto_js.lib.WordArray.create(content);
|
||||
let hash = crypto_js.SHA256(wordArray).toString();
|
||||
blob = new external_buffer_.Blob([hash], { type : 'plain/text' });
|
||||
let hash = hashes.sha256;
|
||||
let blob = new external_buffer_.Blob([hash], { type : 'plain/text' });
|
||||
await client.repository.repoCreateReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
|
||||
139
main.js
139
main.js
@@ -1,5 +1,6 @@
|
||||
import asyncfs from "node:fs/promises";
|
||||
import fs from "fs";
|
||||
import { Blob } from "buffer";
|
||||
import { Blob, File } from "buffer";
|
||||
import * as glob from "glob";
|
||||
|
||||
import core from "@actions/core";
|
||||
@@ -8,6 +9,10 @@ import gitea from "gitea-api";
|
||||
import path from 'path';
|
||||
import CryptoJS from 'crypto-js';
|
||||
|
||||
function getIsTrue(v) {
|
||||
const trueValue = ['true', 'True', 'TRUE']
|
||||
return trueValue.includes(v)
|
||||
}
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
@@ -15,14 +20,14 @@ async function run() {
|
||||
const name = core.getInput("name")
|
||||
const body = getReleaseBody(core.getInput("body"), core.getInput("body_path"))
|
||||
const tag_name = core.getInput("tag_name")
|
||||
const draft = core.getInput("draft") === 'true'
|
||||
const prerelease = core.getInput("prerelease") === 'true'
|
||||
const draft = getIsTrue(core.getInput("draft"))
|
||||
const prerelease = getIsTrue(core.getInput("prerelease"))
|
||||
const files = core.getInput("files")
|
||||
const repository = core.getInput("repository")
|
||||
const token = core.getInput("token")
|
||||
const target_commitish = core.getInput("target_commitish")
|
||||
const md5sum = core.getInput("md5sum")
|
||||
const sha256sum = core.getInput("sha256sum")
|
||||
const md5sum = getIsTrue(core.getInput("md5sum"))
|
||||
const sha256sum = getIsTrue(core.getInput("sha256sum"))
|
||||
|
||||
const [owner, repo] = (repository).split("/")
|
||||
|
||||
@@ -122,6 +127,68 @@ function paths(patterns) {
|
||||
}, []);
|
||||
};
|
||||
|
||||
async function createStreamableFile(fpath) {
|
||||
const name = path.basename(fpath);
|
||||
const handle = await asyncfs.open(fpath);
|
||||
const { size } = await handle.stat();
|
||||
|
||||
const file = new File([], name);
|
||||
file.stream = () => handle.readableWebStream();
|
||||
file.close = async () => await handle?.close();
|
||||
|
||||
// Set correct size otherwise, fetch will encounter UND_ERR_REQ_CONTENT_LENGTH_MISMATCH
|
||||
Object.defineProperty(file, 'size', { get: () => size });
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
async function calculateMultipleHashes(file, algorithms = ['md5', 'sha256']) {
|
||||
const stream = file.stream();
|
||||
const reader = stream.getReader();
|
||||
|
||||
const hashers = algorithms.map(alg => {
|
||||
switch(alg.toLowerCase()) {
|
||||
case 'md5':
|
||||
return { name: 'md5', instance: CryptoJS.algo.MD5.create() };
|
||||
case 'sha1':
|
||||
return { name: 'sha1', instance: CryptoJS.algo.SHA1.create() };
|
||||
case 'sha256':
|
||||
return { name: 'sha256', instance: CryptoJS.algo.SHA256.create() };
|
||||
case 'sha512':
|
||||
return { name: 'sha512', instance: CryptoJS.algo.SHA512.create() };
|
||||
default:
|
||||
throw new Error(`not support hash: ${alg}`);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
const wordArray = CryptoJS.lib.WordArray.create(value);
|
||||
|
||||
hashers.forEach(hasher => {
|
||||
hasher.instance.update(wordArray);
|
||||
});
|
||||
}
|
||||
|
||||
const result = {};
|
||||
hashers.forEach(hasher => {
|
||||
result[hasher.name] = hasher.instance.finalize().toString(CryptoJS.enc.Hex);
|
||||
});
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {gitea.GiteaApi} client
|
||||
@@ -138,32 +205,55 @@ async function uploadFiles(client, owner, repo, release_id, all_files, params) {
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
})
|
||||
// deleted old release attachment
|
||||
const will_deleted = new Set();
|
||||
for (const filepath of all_files) {
|
||||
for (const attachment of attachments) {
|
||||
let will_deleted = [path.basename(filepath), `${path.basename(filepath)}.md5`, `${path.basename(filepath)}.sha256`]
|
||||
if (will_deleted.includes(attachment.name)) {
|
||||
await client.repository.repoDeleteReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
attachmentId: attachment.id,
|
||||
})
|
||||
console.log(`Successfully deleted old release attachment ${attachment.name}`)
|
||||
}
|
||||
will_deleted.add(path.basename(filepath));
|
||||
if (params.md5sum) {
|
||||
will_deleted.add(`${path.basename(filepath)}.md5`);
|
||||
}
|
||||
const content = fs.readFileSync(filepath);
|
||||
let blob = new Blob([content]);
|
||||
if (params.sha256sum) {
|
||||
will_deleted.add(`${path.basename(filepath)}.sha256`);
|
||||
}
|
||||
}
|
||||
for (const attachment of attachments) {
|
||||
if (will_deleted.has(attachment.name)) {
|
||||
await client.repository.repoDeleteReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
attachmentId: attachment.id,
|
||||
})
|
||||
console.log(`Successfully deleted old release attachment ${attachment.name}`)
|
||||
}
|
||||
}
|
||||
// upload new release attachment
|
||||
for (const filepath of all_files) {
|
||||
let curfile = await createStreamableFile(filepath)
|
||||
await client.repository.repoCreateReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
id: release_id,
|
||||
attachment: blob,
|
||||
attachment: curfile,
|
||||
name: path.basename(filepath),
|
||||
})
|
||||
await curfile.close();
|
||||
let algorithms = [];
|
||||
if (params.md5sum) {
|
||||
let wordArray = CryptoJS.lib.WordArray.create(content);
|
||||
let hash = CryptoJS.MD5(wordArray).toString();
|
||||
blob = new Blob([hash], { type : 'plain/text' });
|
||||
algorithms = algorithms.concat('md5');
|
||||
}
|
||||
if (params.sha256sum) {
|
||||
algorithms = algorithms.concat('sha256');
|
||||
}
|
||||
let hashes = {};
|
||||
if (algorithms.length !== 0) {
|
||||
curfile = await createStreamableFile(filepath)
|
||||
hashes = await calculateMultipleHashes(curfile, algorithms)
|
||||
await curfile.close();
|
||||
}
|
||||
if (params.md5sum) {
|
||||
let hash = hashes.md5;
|
||||
let blob = new Blob([hash], { type : 'plain/text' });
|
||||
await client.repository.repoCreateReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
@@ -173,9 +263,8 @@ async function uploadFiles(client, owner, repo, release_id, all_files, params) {
|
||||
})
|
||||
}
|
||||
if (params.sha256sum) {
|
||||
let wordArray = CryptoJS.lib.WordArray.create(content);
|
||||
let hash = CryptoJS.SHA256(wordArray).toString();
|
||||
blob = new Blob([hash], { type : 'plain/text' });
|
||||
let hash = hashes.sha256;
|
||||
let blob = new Blob([hash], { type : 'plain/text' });
|
||||
await client.repository.repoCreateReleaseAttachment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
|
||||
Reference in New Issue
Block a user