summaryrefslogtreecommitdiffstats
path: root/web_src
diff options
context:
space:
mode:
authorFuXiaoHei <fuxiaohei@vip.qq.com>2023-05-19 21:37:57 +0800
committerGitHub <noreply@github.com>2023-05-19 21:37:57 +0800
commitc757765a9e5c2d4f73b1a7c3debe3548c735bd54 (patch)
treeffed7692321760ea4f9c72670ed31437b52ff0e0 /web_src
parent7985cde84df5ee93bfb37b20681d69e67d3f32fc (diff)
downloadgitea-c757765a9e5c2d4f73b1a7c3debe3548c735bd54.tar.gz
gitea-c757765a9e5c2d4f73b1a7c3debe3548c735bd54.zip
Implement actions artifacts (#22738)
Implement action artifacts server api. This change is used for supporting https://github.com/actions/upload-artifact and https://github.com/actions/download-artifact in gitea actions. It can run sample workflow from doc https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts. The api design is inspired by https://github.com/nektos/act/blob/master/pkg/artifacts/server.go and includes some changes from gitea internal structs and methods. Actions artifacts contains two parts: - Gitea server api and storage (this pr implement basic design without some complex cases supports) - Runner communicate with gitea server api (in comming) Old pr https://github.com/go-gitea/gitea/pull/22345 is outdated after actions merged. I create new pr from main branch. ![897f7694-3e0f-4f7c-bb4b-9936624ead45](https://user-images.githubusercontent.com/2142787/219382371-eb3cf810-e4e0-456b-a8ff-aecc2b1a1032.jpeg) Add artifacts list in actions workflow page.
Diffstat (limited to 'web_src')
-rw-r--r--web_src/js/components/RepoActionView.vue50
1 files changed, 50 insertions, 0 deletions
diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue
index 7685627da6..28adfbc6ec 100644
--- a/web_src/js/components/RepoActionView.vue
+++ b/web_src/js/components/RepoActionView.vue
@@ -42,6 +42,18 @@
</div>
</div>
</div>
+ <div class="job-artifacts" v-if="artifacts.length > 0">
+ <div class="job-artifacts-title">
+ {{ locale.artifactsTitle }}
+ </div>
+ <ul class="job-artifacts-list">
+ <li class="job-artifacts-item" v-for="artifact in artifacts" :key="artifact.id">
+ <a class="job-artifacts-link" target="_blank" :href="run.link+'/artifacts/'+artifact.id">
+ <SvgIcon name="octicon-file" class="ui text black job-artifacts-icon" />{{ artifact.name }}
+ </a>
+ </li>
+ </ul>
+ </div>
</div>
<div class="action-view-right">
@@ -102,6 +114,7 @@ const sfc = {
loading: false,
intervalID: null,
currentJobStepsStates: [],
+ artifacts: [],
// provided by backend
run: {
@@ -156,6 +169,15 @@ const sfc = {
this.intervalID = setInterval(this.loadJob, 1000);
},
+ unmounted() {
+ // clear the interval timer when the component is unmounted
+ // even our page is rendered once, not spa style
+ if (this.intervalID) {
+ clearInterval(this.intervalID);
+ this.intervalID = null;
+ }
+ },
+
methods: {
// get the active container element, either the `job-step-logs` or the `job-log-list` in the `job-log-group`
getLogsContainer(idx) {
@@ -259,6 +281,11 @@ const sfc = {
try {
this.loading = true;
+ // refresh artifacts if upload-artifact step done
+ const resp = await this.fetchPost(`${this.actionsURL}/runs/${this.runIndex}/artifacts`);
+ const artifacts = await resp.json();
+ this.artifacts = artifacts['artifacts'] || [];
+
const response = await this.fetchJob();
// save the state to Vue data, then the UI will be updated
@@ -287,6 +314,7 @@ const sfc = {
}
},
+
fetchPost(url, body) {
return fetch(url, {
method: 'POST',
@@ -319,6 +347,7 @@ export function initRepositoryActionView() {
approve: el.getAttribute('data-locale-approve'),
cancel: el.getAttribute('data-locale-cancel'),
rerun: el.getAttribute('data-locale-rerun'),
+ artifactsTitle: el.getAttribute('data-locale-artifacts-title'),
status: {
unknown: el.getAttribute('data-locale-status-unknown'),
waiting: el.getAttribute('data-locale-status-waiting'),
@@ -423,6 +452,27 @@ export function ansiLogToHTML(line) {
padding: 10px;
}
+.job-artifacts-title {
+ font-size: 18px;
+ margin-top: 16px;
+ padding: 16px 10px 0px 20px;
+ border-top: 1px solid var(--color-secondary);
+}
+
+.job-artifacts-item {
+ margin: 5px 0;
+ padding: 6px;
+}
+
+.job-artifacts-list {
+ padding-left: 12px;
+ list-style: none;
+}
+
+.job-artifacts-icon {
+ padding-right: 3px;
+}
+
.job-group-section .job-brief-list .job-brief-item {
margin: 5px 0;
padding: 10px;