mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	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.  Add artifacts list in actions workflow page.
This commit is contained in:
		@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user