diff --git a/roles/upload-artifactory/README.rst b/roles/upload-artifactory/README.rst index d7b13e134..ddc7daf19 100644 --- a/roles/upload-artifactory/README.rst +++ b/roles/upload-artifactory/README.rst @@ -87,6 +87,20 @@ Upload artifacts specified from the executor to artifactory. Any headers that should be passed to ansibles uri module when uploading. + .. zuul:rolevar:: properties + + Properties to set in artifactory. + + Properties can be either strings or lists of strings. + + .. code-block:: yaml + + properties: + property1: value1 + property2: + - value2 + - value3 + .. zuul:rolevar:: metadata Any metadata that should be returned to Zuul together with the diff --git a/roles/upload-artifactory/defaults/main.yaml b/roles/upload-artifactory/defaults/main.yaml deleted file mode 100644 index 19ae6d198..000000000 --- a/roles/upload-artifactory/defaults/main.yaml +++ /dev/null @@ -1 +0,0 @@ -upload_artifactory_workdir: "{{ zuul.executor.work_root }}" diff --git a/roles/upload-artifactory/tasks/upload.yaml b/roles/upload-artifactory/tasks/upload.yaml index 9377a296a..e87bc43c3 100644 --- a/roles/upload-artifactory/tasks/upload.yaml +++ b/roles/upload-artifactory/tasks/upload.yaml @@ -44,19 +44,46 @@ - "'api_key' not in upload_artifactory_instances[zj_artifact.instance]" - "'password' in upload_artifactory_instances[zj_artifact.instance]" -- name: Set artifactory url fact +- name: Set artifactory backend url fact set_fact: - _artifactory_url: "{{ upload_artifactory_instances[zj_artifact.instance].transport | default('https') }}://\ - {{ upload_artifactory_instances[zj_artifact.instance].fqdn }}\ - /artifactory/{{ zj_artifact.dest }}" + _artifactory_backend_url: "\ + {{ upload_artifactory_instances[zj_artifact.instance].transport | default('https') }}://\ + {{ upload_artifactory_instances[zj_artifact.instance].fqdn }}/\ + artifactory/\ + {{ zj_artifact.dest }}" + +- name: Set artifact properties + set_fact: + zj_artifact_properties: >- + {%- set zj_properties = [] -%} + {%- for zj_p in (zj_aps) -%} + {%- if zj_p.value is string -%} + {%- set _ = zj_properties.append(zj_p.key + '=' + zj_p.value) -%} + {%- elif zj_p.value is iterable and zj_p.value is not mapping -%} + {%- set _ = zj_properties.append(zj_p.key + '=' + zj_p.value | join(',')) -%} + {%- endif -%} + {%- endfor -%} + {{ zj_properties | join(';') }} + vars: + zj_aps: "{{ zj_artifact.properties | default({}) | dict2items }}" + +- name: Set upload url + set_fact: + _artifactory_upload_url: "\ + {%- if zj_artifact_properties|length -%} + {{ _artifactory_backend_url }};{{ zj_artifact_properties | default('') }}\ + {%- else -%} + {{ _artifactory_backend_url }}\ + {%- endif -%}" - name: Upload artifact no_log: true uri: user: "{{ upload_artifactory_instances[zj_artifact.instance].user }}" password: "{{ _artifactory_password | default(omit) }}" - url: "{{ _artifactory_url }}" - src: "{{ _undocumented_test_work_dir_ | default(zuul.executor.work_root) }}/artifacts/{{ zj_artifact.src }}" + url: "{{ _artifactory_upload_url }}" + src: "{{ _undocumented_test_work_dir_ | default(zuul.executor.work_root) }}/\ + artifacts/{{ zj_artifact.src }}" headers: "{{ request_header }}" status_code: 201 method: PUT @@ -71,5 +98,5 @@ zuul: artifacts: - name: "{{ zj_artifact.name }}" - url: "{{ _artifactory_url }}" + url: "{{ _artifactory_backend_url }}" metadata: "{{ zj_artifact.metadata | default(omit) }}" diff --git a/test-playbooks/artifactory/run.yaml b/test-playbooks/artifactory/run.yaml index d39b971bf..7190971ea 100644 --- a/test-playbooks/artifactory/run.yaml +++ b/test-playbooks/artifactory/run.yaml @@ -59,6 +59,11 @@ transport: http user: admin api_key: "{{ (artifactory_api_key.content | from_json)['apiKey'] }}" + localhost_properties: + fqdn: localhost:8081 + transport: http + user: admin + api_key: "{{ (artifactory_api_key.content | from_json)['apiKey'] }}" - hosts: all vars: @@ -74,17 +79,59 @@ content: | First file dest: "{{ ansible_user_dir }}/zuul-output/artifacts/test-file.txt" - - name: Set upload_artifactory_manifest fact + - name: Set upload_artifactory_manifest_basic fact set_fact: upload_artifactory_manifest: artifacts: - - name: test-file.txt + - name: test-password.txt src: test-file.txt - dest: generic-repository/path/to/dest/test-file-password.txt + dest: generic-repository/path/to/dest/test-password.txt instance: localhost_password - - name: test-file.txt + - name: test-api-key.txt src: test-file.txt - dest: generic-repository/path/to/dest/test-file-api-key.txt + dest: generic-repository/path/to/dest/test-api-key.txt instance: localhost_api_key + - name: test-properties.txt + src: test-file.txt + dest: generic-repository/path/to/dest/test-properties.txt + instance: localhost_properties + properties: + version: 1.0.0 + supports: + - 1.0.1 + - 1.0.2 roles: - - upload-artifactory + - role: upload-artifactory + + post_tasks: + - name: Load artifacts information from zuul_return + set_fact: + artifacts: "{{ (lookup('file', zuul.executor.work_root + '/results.json') | from_json) ['zuul']['artifacts'] }}" + - name: Expected artifacts are backwards + set_fact: + expected_artifacts: + - name: test-properties.txt + url: http://localhost:8081/artifactory/generic-repository/path/to/dest/test-properties.txt + - name: test-api-key.txt + url: http://localhost:8081/artifactory/generic-repository/path/to/dest/test-api-key.txt + - name: test-password.txt + url: http://localhost:8081/artifactory/generic-repository/path/to/dest/test-password.txt + - name: Assert artifact + assert: + that: + - item.0.name == item.1.name + - item.0.url == item.1.url + loop: "{{ artifacts | zip(expected_artifacts) | list }}" + + - name: Query properties artifact + uri: + method: POST + url: 'http://localhost:8081/artifactory/api/search/aql' + headers: + X-JFrog-Art-Api: "{{ (artifactory_api_key.content | from_json)['apiKey'] }}" + Content-Type: 'text/plain' + body: 'items.find({"$and":[{"repo":"generic-repository"},{"path":"path/to/dest"},{"@version":"1.0.0"}]})' + register: artifact_query + - name: Assert property filtered response + assert: + that: artifact_query.json.results[0].name == 'test-properties.txt'