diff --git a/README.md b/README.md index 82268ec34..6f9b8c442 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,7 @@ or the relevant branch in the Plugin's GitHub repository, as per the table below * [SourceViewVC](docs/CONFIGURING.SourceViewVC.md) * [SourceSVN](docs/CONFIGURING.SourceSVN.md) * [SourceVisualSVNServer](docs/CONFIGURING.SourceVisualSVNServer.md) + * [SourceGitea](docs/CONFIGURING.SourceGitea) 9. Once configured, click the "Return to Repository" link and click either the "Import Everything" or "Import Newest Data" button to perform initial diff --git a/Source/MantisSourceBase.class.php b/Source/MantisSourceBase.class.php index 55a7693db..98331db58 100644 --- a/Source/MantisSourceBase.class.php +++ b/Source/MantisSourceBase.class.php @@ -19,12 +19,12 @@ abstract class MantisSourceBase extends MantisPlugin * a change in the minimum required MantisBT version: 0=1.2; 1=1.3, 2=2.x. * The framework version is incremented when the plugin's core files change. */ - const FRAMEWORK_VERSION = '2.6.0'; + const FRAMEWORK_VERSION = '2.9.1'; /** * Minimum required MantisBT version. * Used to define the default MantisCore dependency for all child plugins; * VCS plugins may override this based on their individual requirements. */ - const MANTIS_VERSION = '2.24.0'; + const MANTIS_VERSION = '2.26.4'; } diff --git a/Source/Source.API.php b/Source/Source.API.php index 9b8ba6ed1..c50ccdafe 100644 --- a/Source/Source.API.php +++ b/Source/Source.API.php @@ -954,7 +954,10 @@ function save() { # Commit timestamp: can't use DATE_ATOM format to insert datetime, # as MySQL < 8.0.19 does not support specifying timezone # @see https://dev.mysql.com/doc/refman/8.0/en/datetime.html - $t_timestamp = $this->timestamp->format( 'Y-m-d H:i:s' ); + # so we convert the timestamp to UTC first. + $t_timestamp = $this->timestamp + ->setTimezone( new DateTimeZone( 'UTC' ) ) + ->format( 'Y-m-d H:i:s' ); if ( 0 == $this->id ) { # create $t_query = "INSERT INTO $t_changeset_table ( repo_id, revision, parent, branch, user_id, diff --git a/Source/SourceIntegration.php b/Source/SourceIntegration.php index 98c93b478..b5c895b2d 100644 --- a/Source/SourceIntegration.php +++ b/Source/SourceIntegration.php @@ -3,12 +3,23 @@ # Copyright (c) 2012 John Reese # Licensed under the MIT license +/** + * @noinspection PhpUnused, + * PhpMissingReturnTypeInspection, PhpMissingParamTypeInspection + */ + +use Mantis\Exceptions\ClientException; + /** * Class SourceIntegrationPlugin * * Child plugin handling the framework's integration with the MantisBT UI */ final class SourceIntegrationPlugin extends MantisSourceBase { + + /** @var SourceChangeset[] */ + protected $changesets; + function register() { $this->name = plugin_lang_get( 'title', 'Source' ); $this->version = self::FRAMEWORK_VERSION; @@ -24,7 +35,17 @@ function hooks() { ); } - function display_changeset_link( $p_event, $p_bug_id ) { + /** + * Display Changeset link. + * + * @param string $p_event Event name + * @param int $p_bug_id User ID + * + * @return string[] + * + * @noinspection PhpUnusedParameterInspection + */ + function display_changeset_link($p_event, $p_bug_id ) { $this->changesets = SourceChangeset::load_by_bug( $p_bug_id, true ); if ( count( $this->changesets ) > 0 ) { @@ -34,6 +55,17 @@ function display_changeset_link( $p_event, $p_bug_id ) { return array(); } + /** + * Display Bug. + * + * @param string $p_event Event name + * @param int $p_bug_id User ID + * + * @return void + * @throws ClientException + * + * @noinspection PhpUnusedParameterInspection + */ function display_bug( $p_event, $p_bug_id ) { require_once( 'Source.ViewAPI.php' ); @@ -78,8 +110,11 @@ function display_bug( $p_event, $p_bug_id ) { /** * When updating user preferences, allowing the user or admin to specify * a version control username to be associated with the account. - * @param string Event name - * @param int User ID + * + * @param string $p_event Event name + * @param int $p_user_id User ID + * + * @noinspection PhpUnusedParameterInspection */ function account_update_form( $p_event, $p_user_id ) { if ( !access_has_global_level( config_get( 'plugin_Source_username_threshold' ) ) ) { @@ -100,15 +135,18 @@ function account_update_form( $p_event, $p_user_id ) { /** * When updating user preferences, allowing the user or admin to specify * a version control username to be associated with the account. - * @param string Event name - * @param int User ID + * + * @param string $p_event Event name + * @param int $p_user_id User ID + * + * @noinspection PhpUnusedParameterInspection */ function account_update( $p_event, $p_user_id ) { if ( !access_has_global_level( config_get( 'plugin_Source_username_threshold' ) ) ) { return; } - $f_vcs_sent = gpc_get_bool( 'Source_vcs', false ); + $f_vcs_sent = gpc_get_bool( 'Source_vcs' ); $f_vcs_username = gpc_get_string( 'Source_vcs_username', '' ); # only load and persist the username if things are set and changed diff --git a/Source/pages/attach.php b/Source/pages/attach.php index 134ddb2a2..d6ab93087 100644 --- a/Source/pages/attach.php +++ b/Source/pages/attach.php @@ -47,4 +47,4 @@ . '&id=' . $t_changeset->id; } -print_successful_redirect( $t_redirect_url ); +print_header_redirect( $t_redirect_url ); diff --git a/Source/pages/detach.php b/Source/pages/detach.php index 60ea86cd6..fb3d92d4a 100644 --- a/Source/pages/detach.php +++ b/Source/pages/detach.php @@ -20,5 +20,5 @@ $t_changeset->save_bugs( $t_user_id ); form_security_purge( 'plugin_Source_detach' ); -print_successful_redirect( plugin_page( 'view', true ) . '&id=' . $t_changeset->id ); +print_header_redirect( plugin_page( 'view', true ) . '&id=' . $t_changeset->id ); diff --git a/Source/pages/edit.php b/Source/pages/edit.php index f4974962c..62b1fbc7f 100644 --- a/Source/pages/edit.php +++ b/Source/pages/edit.php @@ -52,5 +52,5 @@ $t_changeset->save(); form_security_purge( 'plugin_Source_edit' ); -print_successful_redirect( plugin_page( 'view', true ) . '&id=' . $t_changeset->id . '&offset=' . $f_offset ); +print_header_redirect( plugin_page( 'view', true ) . '&id=' . $t_changeset->id . '&offset=' . $f_offset ); diff --git a/Source/pages/manage_config.php b/Source/pages/manage_config.php index a9cb13519..0de147905 100644 --- a/Source/pages/manage_config.php +++ b/Source/pages/manage_config.php @@ -136,5 +136,5 @@ function maybe_set_option( $name, $value ) { form_security_purge( 'plugin_Source_manage_config' ); -print_successful_redirect( plugin_page( 'manage_config_page', true ) ); +print_header_redirect( plugin_page( 'manage_config_page', true ) ); diff --git a/Source/pages/repo_create.php b/Source/pages/repo_create.php index 1e0540fc0..d5d433b2b 100644 --- a/Source/pages/repo_create.php +++ b/Source/pages/repo_create.php @@ -14,4 +14,4 @@ form_security_purge( 'plugin_Source_repo_create' ); -print_successful_redirect( plugin_page( 'repo_update_page', true ) . '&id=' . $t_repo->id ); +print_header_redirect( plugin_page( 'repo_update_page', true ) . '&id=' . $t_repo->id ); diff --git a/Source/pages/repo_delete.php b/Source/pages/repo_delete.php index c52ff8c63..27c6dd7da 100644 --- a/Source/pages/repo_delete.php +++ b/Source/pages/repo_delete.php @@ -16,4 +16,4 @@ SourceRepo::delete( $t_repo->id ); form_security_purge( 'plugin_Source_repo_delete' ); -print_successful_redirect( plugin_page( 'index', true ) ); +print_header_redirect( plugin_page( 'index', true ) ); diff --git a/Source/pages/repo_update.php b/Source/pages/repo_update.php index f232abf62..f3d265a93 100644 --- a/Source/pages/repo_update.php +++ b/Source/pages/repo_update.php @@ -33,5 +33,5 @@ 'id' => $t_repo->id, 'status' => true, ) ); -print_successful_redirect( $t_redirect_url ); +print_header_redirect( $t_redirect_url ); diff --git a/Source/pages/repo_update_mappings.php b/Source/pages/repo_update_mappings.php index b242985a7..8b31f5b21 100644 --- a/Source/pages/repo_update_mappings.php +++ b/Source/pages/repo_update_mappings.php @@ -104,5 +104,5 @@ } form_security_purge( 'plugin_Source_repo_update_mappings' ); -print_successful_redirect( plugin_page( 'repo_manage_page', true ) . '&id=' . $t_repo->id ); +print_header_redirect( plugin_page( 'repo_manage_page', true ) . '&id=' . $t_repo->id ); diff --git a/Source/pages/search.php b/Source/pages/search.php index 162129da7..22c300f64 100644 --- a/Source/pages/search.php +++ b/Source/pages/search.php @@ -10,7 +10,7 @@ $f_offset = gpc_get_int( 'offset', 1 ); $f_perpage = 25; -require_once( config_get( 'plugin_path' ) . 'Source' . DIRECTORY_SEPARATOR . 'Source.FilterAPI.php' ); +require_once( config_get( 'plugin_path' ) . 'Source/Source.FilterAPI.php' ); # Generate listing list( $t_filter, $t_permalink ) = Source_Generate_Filter(); diff --git a/Source/pages/search_page.php b/Source/pages/search_page.php index b3b0c76bd..3b81e4e9f 100644 --- a/Source/pages/search_page.php +++ b/Source/pages/search_page.php @@ -5,7 +5,7 @@ access_ensure_global_level( plugin_config_get( 'view_threshold' ) ); -require_once( config_get( 'plugin_path' ) . 'Source' . DIRECTORY_SEPARATOR . 'Source.FilterAPI.php' ); +require_once( config_get( 'plugin_path' ) . 'Source/Source.FilterAPI.php' ); list( $t_filter, $t_permalink ) = Source_Generate_Filter(); diff --git a/Source/pages/update.php b/Source/pages/update.php index 0cb35658b..f79755bce 100644 --- a/Source/pages/update.php +++ b/Source/pages/update.php @@ -27,5 +27,5 @@ $t_changeset->save(); -print_successful_redirect( plugin_page( 'view', true ) . '&id=' . $t_changeset->id ); +print_header_redirect( plugin_page( 'view', true ) . '&id=' . $t_changeset->id ); diff --git a/Source/pages/view.php b/Source/pages/view.php index 4eabca3a4..995a59576 100644 --- a/Source/pages/view.php +++ b/Source/pages/view.php @@ -6,7 +6,6 @@ access_ensure_global_level( plugin_config_get( 'view_threshold' ) ); $t_can_update = access_has_global_level( plugin_config_get( 'update_threshold' ) ); -/** @noinspection PhpIncludeInspection */ require_once( config_get( 'plugin_path' ) . 'Source/Source.ViewAPI.php' ); $f_changeset_id = gpc_get_int( 'id' ); @@ -187,7 +186,7 @@ function( $p_bug_id ) use ( $t_view_bug_threshold ) { $t_bug_row ) { $t_color_class = html_get_status_css_fg( @@ -215,11 +214,12 @@ function( $p_bug_id ) use ( $t_view_bug_threshold ) { $t_changeset->id, 'bug_id' => $t_bug_id); - print_small_button( - plugin_page( 'detach' ) - . '&' . http_build_query( $t_param ) . $t_security_token, - plugin_lang_get( 'detach' ) + print_form_button( + plugin_page( 'detach' ), + plugin_lang_get( 'detach' ), + array( 'id' => $t_changeset->id, 'bug_id' => $t_bug_id), + $t_security_token, + 'btn btn-round btn-white btn-primary btn-sm' ) ?> diff --git a/SourceGitea/LICENSE b/SourceGitea/LICENSE new file mode 100644 index 000000000..22def7ca3 --- /dev/null +++ b/SourceGitea/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2024 Pasquale Pizzuti + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + diff --git a/SourceGitea/SourceGitea.php b/SourceGitea/SourceGitea.php new file mode 100644 index 000000000..c47f31c61 --- /dev/null +++ b/SourceGitea/SourceGitea.php @@ -0,0 +1,405 @@ +author = 'Pasquale Pizzuti'; + $this->contact = 'paspiz85@gmail.com'; + } + + public function show_type() { + return plugin_lang_get( 'gitea' ); + } + + public function show_changeset( $p_repo, $p_changeset ) { + $t_ref = substr( $p_changeset->revision, 0, 8 ); + $t_branch = $p_changeset->branch; + + return "$t_branch $t_ref"; + } + + public function show_file( $p_repo, $p_changeset, $p_file ) { + return "$p_file->action - $p_file->filename"; + } + + public function url_base( $p_repo ) { + $t_root = rtrim($p_repo->info['hub_root'], '/'); + return $t_root . '/' . $p_repo->info['hub_ownerid'] . '/' . $p_repo->info['hub_repoid']; + } + + public function url_repo( $p_repo, $p_changeset=null ) { + if( empty( $p_repo->info ) ) { + return ''; + } + $t_ref = ''; + if ( !is_null( $p_changeset ) ) { + $t_ref = "/src/branch/$p_changeset->revision"; + } + return $this->url_base( $p_repo ) . $t_ref; + } + + public function url_changeset( $p_repo, $p_changeset ) { + return $this->url_base( $p_repo ) . '/commit/' . $p_changeset->revision; + } + + public function url_file( $p_repo, $p_changeset, $p_file ) { + # Can't link to a deleted file + if( $p_file->action == SourceFile::DELETED ) { + return ''; + } + $t_ref = $p_changeset->revision; + $t_filename = $p_file->getFilename(); + return $this->url_base( $p_repo ) . "/src/branch/$t_ref/$t_filename"; + } + + public function url_diff( $p_repo, $p_changeset, $p_file ) { + return $this->url_changeset( $p_repo, $p_changeset ); + } + + public function update_repo_form( $p_repo ) { + $t_hub_root = null; + $t_hub_ownerid = null; + $t_hub_repoid = null; + $t_hub_app_secret = null; + + if ( isset( $p_repo->info['hub_root'] ) ) { + $t_hub_root = $p_repo->info['hub_root']; + } + if ( isset( $p_repo->info['hub_ownerid'] ) ) { + $t_hub_ownerid = $p_repo->info['hub_ownerid']; + } + if ( isset( $p_repo->info['hub_repoid'] ) ) { + $t_hub_repoid = $p_repo->info['hub_repoid']; + } + if ( isset( $p_repo->info['hub_app_secret'] ) ) { + $t_hub_app_secret = $p_repo->info['hub_app_secret']; + } + if ( isset( $p_repo->info['master_branch'] ) ) { + $t_master_branch = $p_repo->info['master_branch']; + } else { + $t_master_branch = $this->get_default_primary_branches(); + } +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +info['hub_root'] = $f_hub_root; + $p_repo->info['hub_ownerid'] = $f_hub_ownerid; + $p_repo->info['hub_repoid'] = $f_hub_repoid; + $p_repo->info['hub_app_secret'] = $f_hub_app_secret; + + $f_master_branch = gpc_get_string( 'master_branch' ); + $this->validate_branch_list( $f_master_branch ); + + # Update other fields + $p_repo->info['master_branch'] = $f_master_branch; + + return $p_repo; + } + + private function api_uri( $p_repo, $p_path ) { + $t_root = rtrim($p_repo->info['hub_root'], '/'); + $t_uri = $t_root . '/api/' . self::API_VERSION . '/' . $p_path; + + if( isset( $p_repo->info['hub_app_secret'] ) ) { + $t_access_token = $p_repo->info['hub_app_secret']; + if ( !is_blank( $t_access_token ) ) { + $t_uri .= '?access_token=' . $t_access_token; + } + } + + return $t_uri; + } + + public function precommit() { + $f_payload = file_get_contents( "php://input" ); + if( is_null( $f_payload ) ) { + return null; + } + + $t_data = json_decode( $f_payload, true ); + if( is_null( $t_data ) || !isset( $t_data['repository'] ) || !isset( $t_data['repository']['html_url'] )) { + return null; + } + + $t_repourl = $t_data['repository']['html_url']; + $t_repo_table = plugin_table( 'repository', 'Source' ); + + $t_query = "SELECT * FROM $t_repo_table WHERE type = " . db_param(); + $t_result = db_query( $t_query, array( $this->type ) ); + + if ( db_num_rows( $t_result ) < 1 ) { + return null; + } + while ( $t_row = db_fetch_array( $t_result ) ) { + $t_repo = new SourceRepo( $t_row['type'], $t_row['name'], $t_row['url'], $t_row['info'] ); + $t_repo->id = $t_row['id']; + if ( $this->url_base( $t_repo ) == $t_repourl ) { + return array( 'repo' => $t_repo, 'data' => $t_data ); + } + } + return null; + } + + public function commit( $p_repo, $p_data ) { + $t_commits = array(); + foreach( $p_data['commits'] as $t_commit ) { + $t_commits[] = $t_commit['id']; + } + + # extract branch name 'refs/heads/issue/branch-description' => ['refs', 'heads', 'issue/branch-description'] + $t_refData = explode( '/', $p_data['ref'], 3 ); + $t_branch = $t_refData[2]; + + return $this->import_commits( $p_repo, $t_commits, $t_branch ); + } + + public function import_full( $p_repo ) { + echo '
';
+
+		$t_branch = $p_repo->info['master_branch'];
+		if ( is_blank( $t_branch ) ) {
+			$t_branch = $this->get_default_primary_branches();
+		}
+
+		# if we're not allowed everything, populate an array of what we are allowed
+		if( $t_branch != '*' ) {
+			$t_branches_allowed = array_map( 'trim', explode( ',', $t_branch ) );
+		}
+
+		# Always pull back full list of repos
+		$t_ownerid = $p_repo->info['hub_ownerid'];
+		$t_repoid = $p_repo->info['hub_repoid'];
+		$t_uri = $this->api_uri( $p_repo, "repos/$t_ownerid/$t_repoid/branches" );
+
+		$t_member = null;
+		$t_json = json_url( $t_uri, $t_member );
+		if( $t_json === null ) {
+			echo "Could not retrieve data from Gitea at '$t_uri'. Make sure your ";
+			print_link(
+				plugin_page( 'repo_update_page', null, 'Source' )
+				. "&id=$p_repo->id",
+				'repository settings'
+			);
+			echo " are correct.";
+			echo '
'; + return array(); + } + + $t_branches = array(); + foreach( $t_json as $t_branch ) { + if( empty( $t_branches_allowed ) || in_array( $t_branch->name, $t_branches_allowed ) ) { + $t_branches[] = $t_branch; + } + } + + $t_changesets = array(); + + $t_changeset_table = plugin_table( 'changeset', 'Source' ); + + foreach( $t_branches as $t_branch ) { + $t_query = "SELECT parent FROM $t_changeset_table + WHERE repo_id=" . db_param() . ' AND branch=' . db_param() . + ' ORDER BY timestamp'; + $t_result = db_query( $t_query, array( $p_repo->id, $t_branch->name ), 1 ); + + $t_commits = array( $t_branch->commit->id ); + if ( db_num_rows( $t_result ) > 0 ) { + $t_parent = db_result( $t_result ); + echo "Oldest '$t_branch->name' branch parent: '$t_parent'\n"; + + if ( !empty( $t_parent ) ) { + $t_commits[] = $t_parent; + echo "Parents not empty"; + } + echo "Parents empty"; + } + + $t_changesets = array_merge( $t_changesets, $this->import_commits( $p_repo, $t_commits, $t_branch->name ) ); + } + + echo ''; + + return $t_changesets; + } + + public function import_latest( $p_repo ) { + return $this->import_full( $p_repo ); + } + + public function import_commits( $p_repo, $p_commit_ids, $p_branch='' ) { + static $s_parents = array(); + static $s_counter = 0; + $t_ownerid = $p_repo->info['hub_ownerid']; + $t_repoid = $p_repo->info['hub_repoid']; + + if ( is_array( $p_commit_ids ) ) { + $s_parents = array_merge( $s_parents, $p_commit_ids ); + } else { + $s_parents[] = $p_commit_ids; + } + + $t_changesets = array(); + + while( count( $s_parents ) > 0 && $s_counter < 200 ) { + $t_commit_id = array_shift( $s_parents ); + echo "Retrieving $t_commit_id ...
"; + $t_uri = $this->api_uri( $p_repo, "repos/$t_ownerid/$t_repoid/git/commits/$t_commit_id" ); + $t_member = null; + $t_json = json_url( $t_uri, $t_member ); + if ( false === $t_json || is_null( $t_json ) ) { + # Some error occurred retrieving the commit + echo "failed.\n"; + continue; + } else if ( !property_exists( $t_json, 'sha' ) ) { + echo "failed ($t_json->message).\n"; + continue; + } + + list( $t_changeset, $t_commit_parents ) = $this->json_commit_changeset( $p_repo, $t_json, $p_branch ); + if ( $t_changeset ) { + $t_changesets[] = $t_changeset; + } + + $s_parents = array_merge( $s_parents, $t_commit_parents ); + } + + $s_counter = 0; + return $t_changesets; + } + + private function json_commit_changeset( $p_repo, $p_json, $p_branch='' ) { + echo "processing $p_json->sha ... "; + if ( !SourceChangeset::exists( $p_repo->id, $p_json->sha ) ) { + $t_parents = array(); + foreach( $p_json->parents as $t_parent ) { + $t_parents[] = $t_parent->sha; + } + + $t_changeset = new SourceChangeset( + $p_repo->id, + $p_json->sha, + $p_branch, + $p_json->commit->author->date, + $p_json->commit->author->username ?? $p_json->commit->author->name, + $p_json->commit->message + ); + + if ( count( $p_json->parents ) > 0 ) { + $t_parent = $p_json->parents[0]; + $t_changeset->parent = $t_parent->sha; + } + + $t_changeset->author_email = $p_json->author->email ?? "noempty@email.com"; + $t_changeset->committer = $p_json->commit->committer->name; + $t_changeset->committer_email = $p_json->commit->committer->email; + $t_changeset->save(); + + echo "saved.\n"; + return array( $t_changeset, $t_parents ); + } else { + echo "already exists.\n"; + return array( null, array() ); + } + } + +} diff --git a/SourceGitea/lang/strings_english.txt b/SourceGitea/lang/strings_english.txt new file mode 100644 index 000000000..d1bc5732d --- /dev/null +++ b/SourceGitea/lang/strings_english.txt @@ -0,0 +1,17 @@ +The full URL of your Gitea instance'; +$s_plugin_SourceGitea_hub_ownerid = 'Gitea Repository Owner
Organization or user that own the repository'; +$s_plugin_SourceGitea_hub_repoid = 'Gitea Repository Name
Name of the repository'; +$s_plugin_SourceGitea_hub_app_secret = 'Gitea API Key
api key for mantis user (continuous user)'; +$s_plugin_SourceGitea_master_branch = 'Allowed Branches
(comma-separated list, regular expression with /.../ or *)'; + +$s_plugin_SourceGitea_back_repo = 'Back to Repository'; diff --git a/SourceGitweb/SourceGitweb.php b/SourceGitweb/SourceGitweb.php index 69e70f93b..91a5cc0a5 100644 --- a/SourceGitweb/SourceGitweb.php +++ b/SourceGitweb/SourceGitweb.php @@ -11,7 +11,7 @@ class SourceGitwebPlugin extends MantisSourceGitBasePlugin { - const PLUGIN_VERSION = '2.1.1'; + const PLUGIN_VERSION = '2.1.2'; const FRAMEWORK_VERSION_REQUIRED = '2.5.0'; public $type = 'gitweb'; @@ -355,7 +355,7 @@ private function commit_changeset( $p_repo, $p_input, $p_branch='' ) { $t_commit['message'] = trim( str_replace( '
', PHP_EOL, $t_matches[6] ) ); $t_parents = array(); - if ( preg_match_all( '#parent<[^>]*h=([0-9a-f]*)#', $t_gitweb_data, $t_matches ) ) { + if ( preg_match_all( '#parent<[^>]*(?:h=|/commit/)([0-9a-f]*)#', $t_gitweb_data, $t_matches ) ) { foreach( $t_matches[1] as $t_match ) { $t_parents[] = $t_commit['parent'] = $t_match; } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0a8c81bb0..82a89b21d 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,61 @@ specification. # Releases for MantisBT 2.x +## 2.9.1 - 2025-01-26 + +### Fixed + +- Commits time is displayed in the wrong timezone + [#419](https://github.com/mantisbt-plugins/source-integration/issues/419) + + +## 2.9.0 - 2025-01-17 + +### Changed + +- Minimum MantisBT version increased to 2.26.4 + [#266](https://github.com/mantisbt-plugins/source-integration/issues/266) + [#380](https://github.com/mantisbt-plugins/source-integration/issues/380) + +### Fixed + +- checkin.php returning HTTP 200 when errors occur + [#266](https://github.com/mantisbt-plugins/source-integration/issues/266) +- github: API token causes webhook to fail silently + [#380](https://github.com/mantisbt-plugins/source-integration/issues/380) +- gitweb: find parent commits with pathinfo URLs + [#418](https://github.com/mantisbt-plugins/source-integration/issues/418) + + +## [2.8.0] - 2024-09-06 + +### Added + +- New Gitea VCS Plugin, thanks to Pasquale Pizzuti + [#375](https://github.com/mantisbt-plugins/source-integration/issues/375) + +### Fixed + +- Code cleanup + + +## [2.7.0] - 2024-01-04 + +### Changed + +- Minimum MantisBT version increased to 2.26.0 + [#372](https://github.com/mantisbt-plugins/source-integration/issues/372) +- Use print_form_button() to display "Detach" buttons in view page + [#372](https://github.com/mantisbt-plugins/source-integration/issues/372) + +### Fixed + +- PHP 8.2: Creation of dynamic property is deprecated + [#409](https://github.com/mantisbt-plugins/source-integration/issues/409) +- Page redirections trigger a deprecation warning since MantisBT 2.26.0 + [#411](https://github.com/mantisbt-plugins/source-integration/issues/411) + + ## [2.6.0] - 2022-07-15 ### Changed @@ -660,8 +715,12 @@ Support for the 0.x branch ended on 2017-06-30. ## [0.9] - 2008-04-11 -[Unreleased]: https://github.com/mantisbt-plugins/source-integration/compare/v2.6.0...HEAD +[Unreleased]: https://github.com/mantisbt-plugins/source-integration/compare/v2.9.1...HEAD +[2.9.1]: https://github.com/mantisbt-plugins/source-integration/compare/v2.9.0...v2.9.1 +[2.9.0]: https://github.com/mantisbt-plugins/source-integration/compare/v2.8.0...v2.9.0 +[2.8.0]: https://github.com/mantisbt-plugins/source-integration/compare/v2.7.0...v2.8.0 +[2.7.0]: https://github.com/mantisbt-plugins/source-integration/compare/v2.6.0...v2.7.0 [2.6.0]: https://github.com/mantisbt-plugins/source-integration/compare/v2.5.2...v2.6.0 [2.5.2]: https://github.com/mantisbt-plugins/source-integration/compare/v2.5.1...v2.5.2 [2.5.1]: https://github.com/mantisbt-plugins/source-integration/compare/v2.5.0...v2.5.1 diff --git a/docs/CONFIGURING.SourceGitea.md b/docs/CONFIGURING.SourceGitea.md new file mode 100644 index 000000000..61527543a --- /dev/null +++ b/docs/CONFIGURING.SourceGitea.md @@ -0,0 +1,25 @@ +## One time Mantis source integration setup + + - Copy the source integration plugins into mantis "plugins/" subdirectory + - Install required plugins with Mantis plugin admin page + - Get the "API Key" (like 'abcdeb8129a4451a35f47881') from the Source Integration plugin "manage_config_page" + http://mantis.server.intra/plugin.php?page=Source/manage_config_page + +## Gitea setup + + - Login with an Owner (or Administrator) of a Project, go to *Settings -> Webhooks* and + add a Gitea hook with Mantis URL and Mantis Source Integration plugin "API Key": + `http://mantis.server.intra/plugin.php?page=Source/checkin&api_key=abcdeb8129a4451a35f47881` + - Go to your user *Settings -> Applications -> Manage Access Tokens* and create a token. You will need it as "hub_app_secret" in Mantis configuration. + +## Mantis repository setup + + - In Mantis administration, create a repository with a unique name and of type "Gitea". + - URL field is not used by the plugin. + - Gitea config fields are: + - hub_root: root url of the Gitea webserver, required to access Web API + - hub_ownerid: name of the Gitea repository owner, can be an organization or an user. + - hub_repoid: name of the Gitea repository. + - hub_app_secret: the "Private token" of a user. + - master_branch: use '*' or a list of branches to track + diff --git a/tools/bump-version.php b/tools/bump-version.php index 7b0c5afef..dc9a28a5d 100755 --- a/tools/bump-version.php +++ b/tools/bump-version.php @@ -16,8 +16,13 @@ */ // Path to MantisBT root, relative to the Source Integration Plugin's git root -// Change this based on your dev environment's setting -$g_mantis_root = '../../mantisbt'; +// Change this based on your dev environment's setting. The default assumes the +// following directory structure: +// / Dev root +// +-- mantis MantisBT root +// +-- plugins +// +-- source-integration Source Integration Plugin's git root +$g_mantis_root = '../../mantis'; // --------------------------------------------------------------------------- // Main program