Create GitLab releases through API

master
Simon 1 month ago
parent 127c51d909
commit f0bc63d91c

@ -78,10 +78,9 @@ build-release: # This job runs in the build stage, which runs first.
- docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t gitlab.hacknix.net:5050/hacknix/freedmr:latest -t gitlab.hacknix.net:5050/hacknix/freedmr:$CI_COMMIT_TAG-with-proxy -t gitlab.hacknix.net:5050/hacknix/freedmr:development-latest --platform linux/arm/v7,linux/amd64,linux/i386,linux/arm64 --push .
#- docker buildx build --no-cache -f docker-configs/Dockerfile-ci -t hacknix/freedmr:latest -t gitlab.hacknix.net:5050/hacknix/freedmr:latest -t hacknix/$CI_COMMIT_TAG-with-proxy -t gitlab.hacknix.net:5050/hacknix/freedmr:$CI_COMMIT_TAG-with-proxy -t hacknix/freedmr:development-latest -t gitlab.hacknix.net:5050/hacknix/freedmr:development-latest --platform linux/amd64,linux/i386 --push .
- echo "Compile complete."
release:
tag_name: $CI_COMMIT_TAG
name: 'Release $CI_COMMIT_TAG'
description: 'Release created using CI.'
- >-
docker-configs/create-gitlab-release.sh "$CI_COMMIT_TAG" "Release $CI_COMMIT_TAG"
"FreeDMR $CI_COMMIT_TAG release. See the versioned release notes for deployment and validation details."
only:
- tags

@ -0,0 +1,42 @@
#!/bin/sh
set -eu
if [ "$#" -ne 3 ]; then
echo "usage: $0 TAG NAME DESCRIPTION" >&2
exit 2
fi
: "${CI_API_V4_URL:?CI_API_V4_URL is required}"
: "${CI_PROJECT_ID:?CI_PROJECT_ID is required}"
: "${CI_JOB_TOKEN:?CI_JOB_TOKEN is required}"
tag_name=$1
release_name=$2
description=$3
response_file=$(mktemp)
trap 'rm -f "$response_file"' EXIT HUP INT TERM
status=$(curl --silent --show-error \
--output "$response_file" \
--write-out '%{http_code}' \
--request POST \
--header "JOB-TOKEN: $CI_JOB_TOKEN" \
--data-urlencode "tag_name=$tag_name" \
--data-urlencode "name=$release_name" \
--data-urlencode "description=$description" \
"$CI_API_V4_URL/projects/$CI_PROJECT_ID/releases")
case "$status" in
201)
echo "GitLab release created for $tag_name"
;;
409)
echo "GitLab release already exists for $tag_name"
;;
*)
echo "GitLab release creation failed for $tag_name (HTTP $status)" >&2
cat "$response_file" >&2
exit 1
;;
esac

@ -0,0 +1,87 @@
import os
from pathlib import Path
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
HELPER = ROOT / "docker-configs" / "create-gitlab-release.sh"
PIPELINE = ROOT / ".gitlab-ci.yml"
class GitLabReleaseHelperTests(unittest.TestCase):
def setUp(self):
self.temporary = tempfile.TemporaryDirectory(dir=ROOT / "tests")
self.bin_dir = Path(self.temporary.name)
fake_curl = self.bin_dir / "curl"
fake_curl.write_text(
"""#!/bin/sh
output=
while [ \"$#\" -gt 0 ]; do
case \"$1\" in
--output)
output=$2
shift 2
;;
*)
shift
;;
esac
done
printf '%s' \"${FAKE_CURL_BODY:-}\" > \"$output\"
printf '%s' \"${FAKE_CURL_STATUS:-201}\"
""",
encoding="ascii",
)
fake_curl.chmod(0o755)
def tearDown(self):
self.temporary.cleanup()
def run_helper(self, status, body=""):
environment = os.environ.copy()
environment.update(
{
"CI_API_V4_URL": "https://gitlab.example/api/v4",
"CI_PROJECT_ID": "123",
"CI_JOB_TOKEN": "not-logged",
"FAKE_CURL_STATUS": str(status),
"FAKE_CURL_BODY": body,
"PATH": "{}:{}".format(self.bin_dir, environment["PATH"]),
}
)
return subprocess.run(
["/bin/sh", str(HELPER), "v1.2.3", "Release v1.2.3", "Test release"],
check=False,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
env=environment,
)
def test_created_release_succeeds(self):
result = self.run_helper(201)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("release created", result.stdout)
def test_existing_release_is_idempotent(self):
result = self.run_helper(409)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertIn("already exists", result.stdout)
def test_api_failure_is_reported(self):
result = self.run_helper(500, '{"message":"failure"}')
self.assertNotEqual(result.returncode, 0)
self.assertIn("HTTP 500", result.stderr)
self.assertIn('"message":"failure"', result.stderr)
self.assertNotIn("not-logged", result.stderr)
def test_pipeline_does_not_use_runner_release_keyword(self):
pipeline = PIPELINE.read_text(encoding="utf-8")
self.assertNotIn("\n release:\n", pipeline)
self.assertIn("docker-configs/create-gitlab-release.sh", pipeline)
if __name__ == "__main__":
unittest.main()
Loading…
Cancel
Save

Powered by TurnKey Linux.