12 Commits

Author SHA1 Message Date
8402f345cf fix: exit with error if missing informations 🐛 2024-10-30 10:07:42 +13:00
1f18b83405 fix: Make deletion able to use variables 🐛 2024-10-30 10:01:04 +13:00
a2d9b28aa5 fix: debug delete 2024-10-30 09:48:21 +13:00
d2dc5da7d4 fix: Default repo_name is ${GITHUB_REPOSITORY} 2024-10-30 09:47:45 +13:00
14058cc306 print env vars 2024-10-30 09:33:28 +13:00
8170a5179d fix: Image uses env vars not args, doh 🐛 2024-10-30 09:20:53 +13:00
2cb2d440c5 fix: Update base url variable 2024-10-30 07:30:21 +13:00
e80fed6fe7 fix: file not found 🐛 2024-10-29 23:29:27 +13:00
dd653b4a2f fix: Updated environment definition 🐛 2024-10-29 22:45:25 +13:00
6dbfd3e120 fix: action not running 2024-10-29 22:05:05 +13:00
d5932e3574 feat: Use Bash as runtime 2024-10-29 21:07:15 +13:00
Your Name
dbfb2c03bb 0.1.0 2024-08-23 20:07:28 +03:00
9 changed files with 203 additions and 310 deletions

View File

@@ -1,24 +0,0 @@
on:
issues:
types: [opened, edited, reopened]
issue_comment:
types: [created, edited]
jobs:
send_telegram_message:
name: send telegram message
runs-on: ubuntu-latest
steps:
- name: send telegram message
uses: appleboy/telegram-action@master
with:
to: ${{ secrets.TELEGRAM_TO }}
token: ${{ secrets.TELEGRAM_TOKEN }}
message: |
Gitea. Creating new issue
Author: ${{ gitea.actor }}
Repository: ${{ gitea.repository }}
See changes: https://gitea.com/${{ gitea.repository }}/issues/${{ gitea.event.issue.number }}

View File

@@ -1,22 +1,9 @@
FROM rosven9856/php:8.3.10-1 FROM cybercinch/base-alpine-bash:latest
RUN addgroup -g 1000 --system php COPY scripts/docker-entrypoint.sh /entrypoint.sh
RUN adduser -G php --system -D -s /bin/sh -u 1000 php RUN chmod a+x /entrypoint.sh
RUN chown php:php /home/php ENV upload_file="build/Package.zip"
RUN chown php:php /usr/local/bin/composer ENV overwrite_files="false"
RUN mkdir /var/src CMD ["/entrypoint.sh"]
RUN chown -R php:php /var/src
WORKDIR /var/src
COPY ./src /var/src
RUN composer install
USER php
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

View File

@@ -2,8 +2,21 @@
<img width="560" height="260" src="docs/image/github_gitea_actions.jpg" alt="github gitea actions"> <img width="560" height="260" src="docs/image/github_gitea_actions.jpg" alt="github gitea actions">
</p> </p>
# Updating a package in the Gitea system using GitHub Actions # Add/Update a Composer package in Gitea
[![License](https://img.shields.io/github/license/rosven9856/gitea-package-action)](https://github.com/rosven9856/gitea-package-action/blob/master/LICENSE) [![License](https://img.shields.io/github/license/rosven9856/gitea-package-action)](https://github.com/rosven9856/gitea-package-action/blob/master/LICENSE)
This action will update the package version in the Gitea system using the API and output debugging information to the log. This action will update the package version in the Gitea system using the API and output debugging information to the log.
## Example usage
```yaml
steps:
- uses: https://hub.cybercinch.nz/gitea-composer-upload@main
with:
base_url: "https://gitea_instance_url"
access_token: "${{ secrets._G_TOKEN }}"
username: "${{ secrets._G_USERNAME }}"
owner: "owner"
package_version: "${{ env.GITHUB_REF_NAME }}"

View File

@@ -1,30 +1,39 @@
name: "Gitea updating package" name: "Gitea Composer upload package"
description: "Updating a package in the Gitea system using GitHub Actions" description: "Updating a composer package in the Gitea system using GitHub Actions"
inputs: inputs:
gitea_instance_base_url: baseurl:
description: "gitea instance base url" description: "Base URL for Gitea Instance"
required: true required: true
gitea_access_token: username:
description: "gitea access token" description: "Username"
required: true required: true
gitea_owner: access_token:
description: "gitea owner" description: "Access Token"
required: true required: true
gitea_repository: owner:
description: "gitea repository" description: "Package owner"
required: true required: false
gitea_package_registry: version:
description: "gitea package registry" description: "Version of package"
required: true required: true
overwrite_files:
description: "Overwrite package if already exists"
required: false
default: "false"
upload_file:
description: "The file path to upload"
required: false
default: "build/Package.zip"
runs: runs:
using: "docker" using: "docker"
image: "Dockerfile" image: "Dockerfile"
args: env:
- ${{ inputs.gitea_instance_base_url }} baseurl: ${{ inputs.baseurl }}
- ${{ inputs.gitea_access_token }} username: ${{ inputs.username }}
- ${{ inputs.gitea_owner }} access_token: ${{ inputs.access_token }}
- ${{ inputs.gitea_repository }} version: ${{ inputs.version }}
- ${{ inputs.gitea_package_registry }} overwrite_files: ${{ inputs.overwrite_files }}
branding: branding:
icon: 'package' icon: 'package'
color: 'green' color: 'green'

View File

@@ -1,19 +1,17 @@
services: services:
php-fpm: composer-uploader:
container_name: php-fpm container_name: compose-upload-gitea
build: build:
context: ./ context: ./
dockerfile: Dockerfile dockerfile: Dockerfile
environment: environment:
gitea_instance_base_url: ${GITEA_INSTANCE_BASE_URL} baseurl: ${base_url}
gitea_access_token: ${GITEA_ACCESS_TOKEN} access_token: ${access_token}
gitea_owner: ${GITEA_OWNER} username: ${username}
gitea_repository: ${GITEA_REPOSITORY} owner: ${owner}
gitea_package_registry: ${GITEA_PACKAGE_REGISTRY} version: ${version}
repo_name: ${repo_name}
overwrite_files: true
working_dir: /
volumes: volumes:
- ./src:/var/src - ./build:/build
networks:
- bridge
networks:
bridge:
driver: bridge

View File

@@ -1,3 +0,0 @@
#!/bin/sh
php /var/src/app.php

143
scripts/docker-entrypoint.sh Executable file
View File

@@ -0,0 +1,143 @@
#!/bin/bash
# This is to serve as a Plugin for Drone to enable uploading of generic packages to Gitea e.g Ansible Roles
set -eo pipefail
shopt -s nullglob
# check to see if this file is being run or sourced from another script
_is_sourced() {
# https://unix.stackexchange.com/a/215279
[ "${#FUNCNAME[@]}" -ge 2 ] &&
[ "${FUNCNAME[0]}" = '_is_sourced' ] &&
[ "${FUNCNAME[1]}" = 'source' ]
}
# logging functions
action_log() {
local type="$1"
shift
# accept argument string or stdin
local text="$*"
if [ "$#" -eq 0 ]; then text="$(cat)"; fi
local dt
dt="$(date -D 'YYYY-MM-DD hh:mm[:ss]')"
printf '%s [%s] [gitea-composer-uploader]: %s\n' "$dt" "$type" "$text"
}
action_note() {
action_log INF "$@"
}
action_warn() {
action_log WRN "$@" >&2
}
action_error() {
action_log ERR "$@" >&2
}
# Verify that the minimally required password settings are set for operation.
function verify_minimum_env {
if [ -z "$username" ]; then
action_warn "username is required for action operation"
fi
if [ -z "$baseurl" ]; then
action_warn "baseurl setting is required for action operation"
fi
if [ -z "$owner" ]; then
action_warn "owner setting is required for action operation"
fi
if [ -z "$access_token" ]; then
action_warn "access_token setting is required for action operation"
fi
if [ -z "$version" ]; then
action_warn "version setting is required for action operation"
fi
if [ -z "$username" ] ||
[ -z "$baseurl" ] ||
[ -z "$version" ] ||
[ -z "$access_token" ]; then
action_error <<-'EOF'
You need to specify one/all of the following settings:
- username
- access_token
- baseurl
EOF
exit 1
fi
action_note "Sufficient configuration"
}
function delete_file {
no_prefix_version="${version##v}"
username_or_owner=${owner:-$username}
no_owner_repo_name="${GITHUB_REPOSITORY##"$username_or_owner"/}"
# shellcheck disable=SC2154
for file in ${upload_file}; do
action_note "curl -s -o /dev/null -w '%{http_code}' --user \"${username}:${access_token}\" -X DELETE ${baseurl}/api/v1/packages/${owner:-$username}/composer/${owner:-$username}%2F${no_owner_repo_name}/${no_prefix_version}"
response=$(curl -s -o /dev/null -w "%{http_code}" --user "${username}:${access_token}" -X DELETE "${baseurl}/api/v1/packages/${owner:-$username}/composer/${owner:-$username}%2F${no_owner_repo_name}/${no_prefix_version}")
if [ "${response}" == 204 ] || [ "${response}" == 200 ]; then
action_note "Deleted package version ${version} for ${owner:-$username}/${repo_name}"
elif [ "${response}" == 404 ]; then
action_error "Not Found: Odd I cannot locate your package! [bug]"
else
action_error "Response code was ${response}"
fi
done
}
function process_upload_file {
for file in ${upload_file}; do
#action_note "curl -s -o /dev/null -w '%{http_code}' --user \"${username}:${access_token}\" --upload-file ${file} \"${baseurl}/api/packages/${owner:-$username}/composer?version=${version}\""
response=$(curl -s -o /dev/null -w "%{http_code}" --user "${username}:${access_token}" --upload-file "${file}" "${baseurl}/api/packages/${owner:-$username}/composer?version=${version}")
if [ "${response}" == 409 ]; then
action_error "Conflict: File already exists"
if [ "${FILE_OVERWRITE:=$overwrite_files}" == 'true' ]; then
# Delete file as already exists
delete_file
response=$(curl -s -o /dev/null -w "%{http_code}" --user "${username}:${access_token}" --upload-file "${file}" "${baseurl}/api/packages/${owner:-$username}/composer?version=${version}")
if [ "${response}" == 409 ]; then
action_error "Conflict: File already exists"
elif [ "${response}" == 201 ]; then
action_note "File uploaded successfully"
elif [ "${response}" == 400 ]; then
action_error "Bad Request: Version likely already exists"
fi
else
action_error 'Unable to upload file. Maybe toggle overwrite_files setting to true :)'
exit 1
fi
elif [ "${response}" == 201 ]; then
action_note "File uploaded successfully"
elif [ "${response}" == 400 ]; then
action_warn "Bad Request: Version likely already exists"
if [ "${FILE_OVERWRITE:=$overwrite_files}" == 'true' ]; then
# Delete file as already exists
delete_file
response=$(curl -s -o /dev/null -w "%{http_code}" --user "${username}:${access_token}" --upload-file "${file}" "${baseurl}/api/packages/${owner:-$username}/composer?version=${version}")
if [ "${response}" == 409 ]; then
action_error "Conflict: File already exists"
elif [ "${response}" == 201 ]; then
action_note "File uploaded successfully"
elif [ "${response}" == 400 ]; then
action_error "Bad Request: Version likely already exists"
exit 1
fi
else
action_error 'Unable to upload file. Maybe toggle overwrite_files setting to true :)'
exit 1
fi
fi
done
}
_main() {
action_note "Starting"
verify_minimum_env "$@"
process_upload_file "$@"
}
# If we are sourced from elsewhere, don't perform any further actions
if ! _is_sourced; then
_main "$@"
fi

View File

@@ -1,225 +0,0 @@
<?php
\define('RED', "\033[0;31m");
\define('GREEN', "\033[1;32m");
\define('YELLOW', "\033[1;33m");
\define('LITE_CYAN', "\e[96m");
\define('NC', "\033[0m");
function sendRequest ($method = 'GET', $endpoint = '', $data = []): array {
if (!\extension_loaded('curl')) {
throw new \Exception('CURL extension is not loaded');
}
$curl = \curl_init();
if(!$curl) {
throw new \Exception('CURL extension is not loaded');
}
$payload = '';
if (isset($data['request']) && \is_array($data['request']) && \count($data['request']) > 0) {
$payload = \json_encode($data['request']);
}
$fh = null;
$fileSize = 0;
if (isset($data['file']) && !empty($data['file']) && \file_exists($data['file'])) {
$fh = \fopen($data['file'], 'r');
$fileSize = \filesize($data['file']);
}
if (isset($data['user']) && !empty($data['user'])) {
\curl_setopt($curl, CURLOPT_USERPWD, $data['user'] . ':' . \getenv('gitea_access_token'));
} else {
$endpoint .= '?access_token=' . \getenv('gitea_access_token');
}
\curl_setopt($curl, CURLOPT_URL, \getenv('gitea_instance_base_url') . $endpoint /* . '?access_token=' . \getenv('gitea_access_token')*/);
\curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
\curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
\curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
\curl_setopt($curl, CURLOPT_HEADER, true);
if ($method === 'POST' || $method === 'PUT') {
if (!empty($payload)) {
\curl_setopt($curl, CURLOPT_POSTFIELDS, $payload);
\curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
}
}
if ($method === 'PUT') {
\curl_setopt($curl, CURLOPT_PUT, true);
}
if ($fh) {
\curl_setopt($curl, CURLOPT_INFILE, $fh);
\curl_setopt($curl, CURLOPT_INFILESIZE, $fileSize);
}
\curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
\curl_setopt($curl, CURLOPT_TIMEOUT, 20);
$response = \curl_exec($curl);
if(\curl_errno($curl) > 0) {
throw new \Exception('Curl error: #' . \curl_errno($curl) . ' - ' . \curl_error($curl));
}
$header = \substr($response, 0, \curl_getinfo($curl, CURLINFO_HEADER_SIZE));
$body = \substr($response, \curl_getinfo($curl, CURLINFO_HEADER_SIZE));
$httpCode = (int) \curl_getinfo($curl, CURLINFO_HTTP_CODE);
$contentType = \curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
$headers = \explode("\r\n", $header);
\curl_close($curl);
if (isset($data['file']) && !empty($data['file']) && \file_exists($data['file'])) {
\fclose($fh);
}
return [
'http_code' => $httpCode,
'content_type' => $contentType,
'headers' => $headers,
'body' => $body,
];
}
function responseEncode (array $response): mixed {
$data = [];
if ($response['content_type'] !== 'application/json;charset=utf-8') {
return $data;
}
$data = \json_decode($response['body'], true);
if (\json_last_error() !== JSON_ERROR_NONE) {
throw new \Exception('Invalid response json: ' . json_last_error_msg());
}
return $data;
}
function showTerminalMessage (string $message = '', string $color = ''): void
{
echo $color . $message . NC . "\r\n";
}
try {
if (empty(\getenv('gitea_instance_base_url'))) {
throw new \Exception('gitea_instance_base_url empty');
}
if (empty(\getenv('gitea_access_token'))) {
throw new \Exception('gitea_access_token empty');
}
if (empty(\getenv('gitea_owner'))) {
throw new \Exception('gitea_owner empty');
}
if (empty(\getenv('gitea_repository'))) {
throw new \Exception('gitea_repository empty');
}
if (empty(\getenv('gitea_package_registry'))) {
throw new \Exception('gitea_package_registry empty');
}
if (!\in_array(\getenv('gitea_package_registry'), ['composer'])) {
throw new \Exception('Package registry {' . \getenv('gitea_package_registry') . '} is not supported');
}
$response = sendRequest('GET', '/api/v1/user');
if ($response['http_code'] !== 200) {
throw new \Exception('Failed to get user information. Access denied. Response http code: ' . $response['http_code']);
}
$data = responseEncode($response);
if ($response['http_code'] !== 200) {
throw new \Exception('Failed to get user information. Response http code: ' . $response['http_code'] . ', Message: ' . $data['message']);
}
$user = $data;
$login = $user['login'];
showTerminalMessage('User data: OK', GREEN);
$response = sendRequest('GET', '/api/v1/repos/' . \getenv('gitea_owner') . '/' . \getenv('gitea_repository') . '/releases', [
'user' => $login,
]);
if ($response['http_code'] !== 200) {
throw new \Exception('Failed to get repository releases information. Access denied. Response http code: ' . $response['http_code']);
}
$data = responseEncode($response);
if ($response['http_code'] !== 200) {
throw new \Exception('Failed to get repository releases information. Response http code: ' . $response['http_code'] . ', Message: ' . $data['message']);
}
if (!isset($data[0]) || !\is_array($data[0])) {
throw new \Exception('Unexpected release data structure');
}
$lastRelease = $data[0];
$tag = $lastRelease['tag_name'];
showTerminalMessage('Last release data: OK', GREEN);
$response = sendRequest('GET', '/api/v1/repos/' . \getenv('gitea_owner') . '/' . \getenv('gitea_repository') . '/archive/' . $tag . '.zip', [
'user' => $login,
]);
$zipContent = $response['body'];
if ($response['http_code'] !== 200) {
throw new \Exception('Failed receiving zip archive. Response http code: ' . $response['http_code']);
}
if (empty($response['body'])) {
throw new \Exception('Failed receiving zip archive. Empty file');
}
\file_put_contents(__DIR__ . '/package.zip', $zipContent);
showTerminalMessage('Download zip archive: OK', GREEN);
$response = sendRequest('PUT', '/api/packages/' . \getenv('gitea_owner') . '/composer?version=' . $tag, [
'user' => $login,
'file' => __DIR__ . '/package.zip',
]);
\unlink(__DIR__ . '/package.zip');
if ($response['http_code'] !== 201) {
$data = responseEncode($response);
throw new \Exception('Failed update package. Response http code: ' . $response['http_code'] . ', Message: ' . $data['errors'][0]['message']);
}
showTerminalMessage('Update package: OK', GREEN);
} catch (\Exception $e) {
showTerminalMessage("\r\n");
showTerminalMessage( 'FAILED!', RED);
showTerminalMessage( "Error: " . $e->getMessage(), RED);
exit(1);
}
showTerminalMessage("\r\n");
showTerminalMessage('SUCCESS!', GREEN);

View File

@@ -1,5 +0,0 @@
{
"require": {
"ext-curl": "*"
}
}