mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge remote-tracking branch 'inventree/master'
This commit is contained in:
commit
9c0d060bf2
26
.github/release.yml
vendored
Normal file
26
.github/release.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# .github/release.yml
|
||||
|
||||
changelog:
|
||||
categories:
|
||||
- title: Breaking Changes
|
||||
labels:
|
||||
- Semver-Major
|
||||
- breaking
|
||||
- title: New Features
|
||||
labels:
|
||||
- Semver-Minor
|
||||
- enhancement
|
||||
- title: Bug Fixes
|
||||
labels:
|
||||
- Semver-Patch
|
||||
- bug
|
||||
- title: Devops / Setup Changes
|
||||
labels:
|
||||
- docker
|
||||
- setup
|
||||
- demo
|
||||
- CI
|
||||
- security
|
||||
- title: Other Changes
|
||||
labels:
|
||||
- "*"
|
20
.github/workflows/docker.yaml
vendored
20
.github/workflows/docker.yaml
vendored
@ -2,7 +2,6 @@
|
||||
# This workflow runs under any of the following conditions:
|
||||
#
|
||||
# - Push to the master branch
|
||||
# - Push to the stable branch
|
||||
# - Publish release
|
||||
#
|
||||
# The following actions are performed:
|
||||
@ -21,7 +20,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- 'stable'
|
||||
|
||||
jobs:
|
||||
|
||||
@ -29,12 +27,15 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v2
|
||||
- name: Version Check
|
||||
run: |
|
||||
python3 ci/check_version_number.py
|
||||
python3 ci/version_check.py
|
||||
echo "git_commit_hash=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
|
||||
echo "git_commit_date=$(git show -s --format=%ci)" >> $GITHUB_ENV
|
||||
- name: Run Unit Tests
|
||||
@ -65,5 +66,14 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
target: production
|
||||
tags: inventree/inventree:${{ env.docker_tag }}
|
||||
build-args: commit_hash=${{ env.git_commit_hash }},commit_date=${{ env.git_commit_date }},commit_tag=${{ env.docker_tag }}
|
||||
tags: ${{ env.docker_tags }}
|
||||
build-args: |
|
||||
commit_hash=${{ env.git_commit_hash }}
|
||||
commit_date=${{ env.git_commit_date }}
|
||||
- name: Push to Stable Branch
|
||||
uses: ad-m/github-push-action@master
|
||||
if: env.stable_release == 'true'
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: stable
|
||||
force: true
|
||||
|
3
.github/workflows/qc_checks.yaml
vendored
3
.github/workflows/qc_checks.yaml
vendored
@ -91,9 +91,6 @@ jobs:
|
||||
cache: 'pip'
|
||||
- name: Run pre-commit Checks
|
||||
uses: pre-commit/action@v2.0.3
|
||||
- name: Check version number
|
||||
run: |
|
||||
python3 ci/check_version_number.py
|
||||
|
||||
python:
|
||||
name: Tests - inventree-python
|
||||
|
@ -137,6 +137,7 @@ The tags describe issues and PRs in multiple areas:
|
||||
| Area | Name | Description |
|
||||
|---|---|---|
|
||||
| Type Labels | | |
|
||||
| | breaking | Indicates a major update or change which breaks compatibility |
|
||||
| | bug | Identifies a bug which needs to be addressed |
|
||||
| | dependency | Relates to a project dependency |
|
||||
| | duplicate | Duplicate of another issue or PR |
|
||||
|
@ -105,10 +105,9 @@ COPY docker/init.sh ${INVENTREE_MNG_DIR}/init.sh
|
||||
WORKDIR ${INVENTREE_MNG_DIR}
|
||||
|
||||
# Drop to the inventree user for the production image
|
||||
RUN adduser inventree
|
||||
RUN chown -R inventree:inventree ${INVENTREE_HOME}
|
||||
|
||||
USER inventree
|
||||
#RUN adduser inventree
|
||||
#RUN chown -R inventree:inventree ${INVENTREE_HOME}
|
||||
#USER inventree
|
||||
|
||||
# Install InvenTree packages
|
||||
RUN pip3 install --user --disable-pip-version-check -r ${INVENTREE_HOME}/requirements.txt
|
||||
|
@ -4,11 +4,17 @@ InvenTree API version information
|
||||
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 51
|
||||
INVENTREE_API_VERSION = 53
|
||||
|
||||
"""
|
||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||
|
||||
v52 -> 2022-06-01 : https://github.com/inventree/InvenTree/pull/3110
|
||||
- Adds extra search fields to the BuildOrder list API endpoint
|
||||
|
||||
v52 -> 2022-05-31 : https://github.com/inventree/InvenTree/pull/3103
|
||||
- Allow part list API to be searched by supplier SKU
|
||||
|
||||
v51 -> 2022-05-24 : https://github.com/inventree/InvenTree/pull/3058
|
||||
- Adds new fields to the SalesOrderShipment model
|
||||
|
||||
|
@ -106,8 +106,10 @@ class BuildList(APIDownloadMixin, generics.ListCreateAPIView):
|
||||
|
||||
search_fields = [
|
||||
'reference',
|
||||
'part__name',
|
||||
'title',
|
||||
'part__name',
|
||||
'part__IPN',
|
||||
'part__description',
|
||||
]
|
||||
|
||||
def get_queryset(self):
|
||||
|
@ -375,7 +375,7 @@ onPanelLoad('attachments', function() {
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
location.reload();
|
||||
$('#attachment-table').bootstrapTable('refresh');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -3,7 +3,6 @@
|
||||
from django.test import TestCase
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db.utils import IntegrityError
|
||||
|
||||
from InvenTree import status_codes as status
|
||||
|
||||
@ -194,14 +193,13 @@ class BuildTest(BuildTestBase):
|
||||
b.save()
|
||||
|
||||
def test_duplicate_bom_line(self):
|
||||
# Try to add a duplicate BOM item - it should fail!
|
||||
# Try to add a duplicate BOM item - it should be allowed
|
||||
|
||||
with self.assertRaises(IntegrityError):
|
||||
BomItem.objects.create(
|
||||
part=self.assembly,
|
||||
sub_part=self.sub_part_1,
|
||||
quantity=99
|
||||
)
|
||||
BomItem.objects.create(
|
||||
part=self.assembly,
|
||||
sub_part=self.sub_part_1,
|
||||
quantity=99
|
||||
)
|
||||
|
||||
def allocate_stock(self, output, allocations):
|
||||
"""
|
||||
|
@ -1425,6 +1425,20 @@ class InvenTreeUserSetting(BaseInvenTreeSetting):
|
||||
'validator': bool,
|
||||
},
|
||||
|
||||
'SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS': {
|
||||
'name': _('Seach Supplier Parts'),
|
||||
'description': _('Display supplier parts in search preview window'),
|
||||
'default': True,
|
||||
'validator': bool,
|
||||
},
|
||||
|
||||
'SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS': {
|
||||
'name': _('Search Manufacturer Parts'),
|
||||
'description': _('Display manufacturer parts in search preview window'),
|
||||
'default': True,
|
||||
'validator': bool,
|
||||
},
|
||||
|
||||
'SEARCH_HIDE_INACTIVE_PARTS': {
|
||||
'name': _("Hide Inactive Parts"),
|
||||
'description': _('Excluded inactive parts from search preview window'),
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1387,6 +1387,7 @@ class PartList(APIDownloadMixin, generics.ListCreateAPIView):
|
||||
'keywords',
|
||||
'category__name',
|
||||
'manufacturer_parts__MPN',
|
||||
'supplier_parts__SKU',
|
||||
]
|
||||
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
# Generated by Django 3.2.13 on 2022-05-31 01:42
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('part', '0076_auto_20220516_0819'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='bomitem',
|
||||
unique_together=set(),
|
||||
),
|
||||
]
|
@ -2899,9 +2899,6 @@ class BomItem(models.Model, DataImportMixin):
|
||||
class Meta:
|
||||
verbose_name = _("BOM Item")
|
||||
|
||||
# Prevent duplication of parent/child rows
|
||||
unique_together = ('part', 'sub_part')
|
||||
|
||||
def __str__(self):
|
||||
return "{n} x {child} to make {parent}".format(
|
||||
parent=self.part.full_name,
|
||||
|
@ -16,6 +16,8 @@
|
||||
<tbody>
|
||||
{% include "InvenTree/settings/setting.html" with key="SEARCH_PREVIEW_SHOW_PARTS" user_setting=True icon='fa-shapes' %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SEARCH_HIDE_INACTIVE_PARTS" user_setting=True icon='fa-eye-slash' %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS" user_setting=True icon='fa-building' %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS" user_setting=True icon='fa-industry' %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SEARCH_PREVIEW_SHOW_CATEGORIES" user_setting=True icon='fa-sitemap' %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SEARCH_PREVIEW_SHOW_STOCK" user_setting=True icon='fa-boxes' %}
|
||||
{% include "InvenTree/settings/setting.html" with key="SEARCH_PREVIEW_HIDE_UNAVAILABLE_STOCK" user_setting=True icon='fa-eye-slash' %}
|
||||
|
@ -2,6 +2,18 @@
|
||||
|
||||
<div id='attachment-buttons'>
|
||||
<div class='btn-group' role='group'>
|
||||
<div class='btn-group'>
|
||||
<button class='btn btn-primary dropdown-toggle' type='buton' data-bs-toggle='dropdown' title='{% trans "Actions" %}'>
|
||||
<span class='fas fa-tools'></span> <span class='caret'></span>
|
||||
</button>
|
||||
<ul class='dropdown-menu'>
|
||||
<li>
|
||||
<a class='dropdown-item' href='#' id='multi-attachment-delete' title='{% trans "Delete selected attachments" %}'>
|
||||
<span class='fas fa-trash-alt icon-red'></span> {% trans "Delete Attachments" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{% include "filter_list.html" with id="attachments" %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -57,6 +57,75 @@ function addAttachmentButtonCallbacks(url, fields={}) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Construct a form to delete attachment files
|
||||
*/
|
||||
function deleteAttachments(attachments, url, options={}) {
|
||||
|
||||
if (attachments.length == 0) {
|
||||
console.warn('deleteAttachments function called with zero attachments provided');
|
||||
return;
|
||||
}
|
||||
|
||||
function renderAttachment(attachment, opts={}) {
|
||||
|
||||
var icon = '';
|
||||
|
||||
if (attachment.filename) {
|
||||
icon = `<span class='fas fa-file-alt'></span>`;
|
||||
} else if (attachment.link) {
|
||||
icon = `<span class='fas fa-link'></span>`;
|
||||
}
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td>${icon}</td>
|
||||
<td>${attachment.filename || attachment.link}</td>
|
||||
<td>${attachment.comment}</td>
|
||||
</tr>`;
|
||||
}
|
||||
|
||||
var rows = '';
|
||||
|
||||
attachments.forEach(function(att) {
|
||||
rows += renderAttachment(att);
|
||||
});
|
||||
|
||||
var html = `
|
||||
<div class='alert alert-block alert-danger'>
|
||||
{% trans "All selected attachments will be deleted" %}
|
||||
</div>
|
||||
<table class='table table-striped table-condensed'>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{% trans "Attachment" %}</th>
|
||||
<th>{% trans "Comment" %}</th>
|
||||
</tr>
|
||||
${rows}
|
||||
</table>
|
||||
`;
|
||||
|
||||
constructFormBody({}, {
|
||||
method: 'DELETE',
|
||||
title: '{% trans "Delete Attachments" %}',
|
||||
preFormContent: html,
|
||||
onSubmit: function(fields, opts) {
|
||||
inventreeMultiDelete(
|
||||
url,
|
||||
attachments,
|
||||
{
|
||||
modal: opts.modal,
|
||||
success: function() {
|
||||
// Refresh the table once all attachments are deleted
|
||||
$('#attachment-table').bootstrapTable('refresh');
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function reloadAttachmentTable() {
|
||||
|
||||
$('#attachment-table').bootstrapTable('refresh');
|
||||
@ -71,6 +140,15 @@ function loadAttachmentTable(url, options) {
|
||||
|
||||
addAttachmentButtonCallbacks(url, options.fields || {});
|
||||
|
||||
// Add callback for the 'multi delete' button
|
||||
$('#multi-attachment-delete').click(function() {
|
||||
var attachments = getTableData(table);
|
||||
|
||||
if (attachments.length > 0) {
|
||||
deleteAttachments(attachments, url);
|
||||
}
|
||||
});
|
||||
|
||||
$(table).inventreeTable({
|
||||
url: url,
|
||||
name: options.name || 'attachments',
|
||||
@ -80,7 +158,9 @@ function loadAttachmentTable(url, options) {
|
||||
sortable: true,
|
||||
search: true,
|
||||
queryParams: options.filters || {},
|
||||
uniqueId: 'pk',
|
||||
onPostBody: function() {
|
||||
|
||||
// Add callback for 'edit' button
|
||||
$(table).find('.button-attachment-edit').click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
@ -105,15 +185,14 @@ function loadAttachmentTable(url, options) {
|
||||
$(table).find('.button-attachment-delete').click(function() {
|
||||
var pk = $(this).attr('pk');
|
||||
|
||||
constructForm(`${url}${pk}/`, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
var attachment = $(table).bootstrapTable('getRowByUniqueId', pk);
|
||||
deleteAttachments([attachment], url);
|
||||
});
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
checkbox: true,
|
||||
},
|
||||
{
|
||||
field: 'attachment',
|
||||
title: '{% trans "Attachment" %}',
|
||||
|
@ -151,6 +151,46 @@ function updateSearch() {
|
||||
);
|
||||
}
|
||||
|
||||
if (checkPermission('part') && checkPermission('purchase_order')) {
|
||||
|
||||
var params = {
|
||||
part_detail: true,
|
||||
supplier_detail: true,
|
||||
manufacturer_detail: true,
|
||||
};
|
||||
|
||||
if (user_settings.SEARCH_HIDE_INACTIVE_PARTS) {
|
||||
// Return *only* active parts
|
||||
params.active = true;
|
||||
}
|
||||
|
||||
if (user_settings.SEARCH_PREVIEW_SHOW_SUPPLIER_PARTS) {
|
||||
addSearchQuery(
|
||||
'supplierpart',
|
||||
'{% trans "Supplier Parts" %}',
|
||||
'{% url "api-supplier-part-list" %}',
|
||||
params,
|
||||
renderSupplierPart,
|
||||
{
|
||||
url: '/supplier-part',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (user_settings.SEARCH_PREVIEW_SHOW_MANUFACTURER_PARTS) {
|
||||
addSearchQuery(
|
||||
'manufacturerpart',
|
||||
'{% trans "Manufacturer Parts" %}',
|
||||
'{% url "api-manufacturer-part-list" %}',
|
||||
params,
|
||||
renderManufacturerPart,
|
||||
{
|
||||
url: '/manufacturer-part',
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (checkPermission('part_category') && user_settings.SEARCH_PREVIEW_SHOW_CATEGORIES) {
|
||||
// Search for matching part categories
|
||||
addSearchQuery(
|
||||
|
@ -4,20 +4,79 @@ Ensure that the release tag matches the InvenTree version number:
|
||||
master / main branch:
|
||||
- version number must end with 'dev'
|
||||
|
||||
stable branch:
|
||||
- version number must *not* end with 'dev'
|
||||
- version number cannot already exist as a release tag
|
||||
|
||||
tagged branch:
|
||||
- version number must match tag being built
|
||||
- version number cannot already exist as a release tag
|
||||
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
def get_existing_release_tags():
|
||||
"""Request information on existing releases via the GitHub API"""
|
||||
|
||||
response = requests.get('https://api.github.com/repos/inventree/inventree/releases')
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ValueError(f'Unexpected status code from GitHub API: {response.status_code}')
|
||||
|
||||
data = json.loads(response.text)
|
||||
|
||||
# Return a list of all tags
|
||||
tags = []
|
||||
|
||||
for release in data:
|
||||
tag = release['tag_name'].strip()
|
||||
match = re.match(r"^.*(\d+)\.(\d+)\.(\d+).*$", tag)
|
||||
|
||||
if len(match.groups()) != 3:
|
||||
print(f"Version '{tag}' did not match expected pattern")
|
||||
continue
|
||||
|
||||
tags.append([int(x) for x in match.groups()])
|
||||
|
||||
return tags
|
||||
|
||||
|
||||
def check_version_number(version_string):
|
||||
"""Check the provided version number.
|
||||
|
||||
Returns True if the provided version is the 'newest' InvenTree release
|
||||
"""
|
||||
|
||||
print(f"Checking version '{version_string}'")
|
||||
|
||||
# Check that the version string matches the required format
|
||||
match = re.match(r"^(\d+)\.(\d+)\.(\d+)(?: dev)?$", version_string)
|
||||
|
||||
if not match or len(match.groups()) != 3:
|
||||
raise ValueError(f"Version string '{version_string}' did not match required pattern")
|
||||
|
||||
version_tuple = [int(x) for x in match.groups()]
|
||||
|
||||
# Look through the existing releases
|
||||
existing = get_existing_release_tags()
|
||||
|
||||
# Assume that this is the highest release, unless told otherwise
|
||||
highest_release = True
|
||||
|
||||
for release in existing:
|
||||
if release == version_tuple:
|
||||
raise ValueError(f"Duplicate release '{version_string}' exists!")
|
||||
|
||||
if release > version_tuple:
|
||||
highest_release = False
|
||||
print(f"Found newer release: {str(release)}")
|
||||
|
||||
return highest_release
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
@ -49,24 +108,12 @@ if __name__ == '__main__':
|
||||
|
||||
print(f"InvenTree Version: '{version}'")
|
||||
|
||||
highest_release = check_version_number(version)
|
||||
|
||||
# Determine which docker tag we are going to use
|
||||
docker_tag = None
|
||||
docker_tags = None
|
||||
|
||||
if GITHUB_REF_TYPE == 'branch' and ('stable' in GITHUB_REF or 'stable' in GITHUB_BASE_REF):
|
||||
print("Checking requirements for 'stable' release branch:")
|
||||
|
||||
pattern = r"^\d+(\.\d+)+$"
|
||||
result = re.match(pattern, version)
|
||||
|
||||
if result is None:
|
||||
print(f"Version number '{version}' does not match required pattern for stable branch")
|
||||
sys.exit(1)
|
||||
else:
|
||||
print(f"Version number '{version}' matches stable branch")
|
||||
|
||||
docker_tag = 'stable'
|
||||
|
||||
elif GITHUB_REF_TYPE == 'tag':
|
||||
if GITHUB_REF_TYPE == 'tag':
|
||||
# GITHUB_REF should be of th eform /refs/heads/<tag>
|
||||
version_tag = GITHUB_REF.split('/')[-1]
|
||||
print(f"Checking requirements for tagged release - '{version_tag}':")
|
||||
@ -77,7 +124,10 @@ if __name__ == '__main__':
|
||||
|
||||
# TODO: Check if there is already a release with this tag!
|
||||
|
||||
docker_tag = version_tag
|
||||
if highest_release:
|
||||
docker_tags = [version_tag, 'stable']
|
||||
else:
|
||||
docker_tags = [version_tag]
|
||||
|
||||
elif GITHUB_REF_TYPE == 'branch':
|
||||
# Otherwise we know we are targetting the 'master' branch
|
||||
@ -92,7 +142,7 @@ if __name__ == '__main__':
|
||||
else:
|
||||
print(f"Version number '{version}' matches development branch")
|
||||
|
||||
docker_tag = 'latest'
|
||||
docker_tags = ['latest']
|
||||
|
||||
else:
|
||||
print("Unsupported branch / version combination:")
|
||||
@ -102,13 +152,20 @@ if __name__ == '__main__':
|
||||
print("GITHUB_REF:", GITHUB_REF)
|
||||
sys.exit(1)
|
||||
|
||||
if docker_tag is None:
|
||||
if docker_tags is None:
|
||||
print("Docker tag could not be determined")
|
||||
sys.exit(1)
|
||||
|
||||
print(f"Version check passed for '{version}'!")
|
||||
print(f"Docker tag: '{docker_tag}'")
|
||||
print(f"Docker tags: '{docker_tags}'")
|
||||
|
||||
# Ref: https://getridbug.com/python/how-to-set-environment-variables-in-github-actions-using-python/
|
||||
with open(os.getenv('GITHUB_ENV'), 'a') as env_file:
|
||||
env_file.write(f"docker_tag={docker_tag}\n")
|
||||
|
||||
# Construct tag string
|
||||
tags = ",".join([f"inventree/inventree:{tag}" for tag in docker_tags])
|
||||
|
||||
env_file.write(f"docker_tags={tags}\n")
|
||||
|
||||
if GITHUB_REF_TYPE == 'tag' and highest_release:
|
||||
env_file.write("stable_release=true\n")
|
Loading…
Reference in New Issue
Block a user