Skip to content

Commit a5f55d5

Browse files
author
epriestley
committed
Provide a real object ("PhabricatorRepositoryPushEvent") to represent an entire push transaction
Summary: Ref T4677. Currently, we record individual actions in a push as PhabricatorRepositoryPushLogs, but tie them together only loosely with a `transactionKey`. Provide a real PushEvent object, and move some of the denormalized fields to it. This primarily just gives us more robust infrastructure for building, e.g., email about pushes, for T4677, since we can act on real PHIDs rather than passing awkward identifiers around. Test Plan: - Performed migration. - Looked at database for consistency. - Browsed/queried push logs. - Pushed a bunch of stuff. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T4677 Differential Revision: https://secure.phabricator.com/D8615
1 parent c828160 commit a5f55d5

12 files changed

+361
-65
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CREATE TABLE {$NAMESPACE}_repository.repository_pushevent (
2+
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
3+
phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
4+
repositoryPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
5+
epoch INT UNSIGNED NOT NULL,
6+
pusherPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
7+
remoteAddress INT UNSIGNED,
8+
remoteProtocol VARCHAR(32),
9+
rejectCode INT UNSIGNED NOT NULL,
10+
rejectDetails VARCHAR(64) COLLATE utf8_bin,
11+
12+
UNIQUE KEY `key_phid` (phid),
13+
KEY `key_repository` (repositoryPHID)
14+
15+
) ENGINE=InnoDB, COLLATE=utf8_general_ci;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
ALTER TABLE {$NAMESPACE}_repository.repository_pushlog
2+
ADD pushEventPHID VARCHAR(64) NOT NULL COLLATE utf8_bin AFTER epoch;
3+
4+
ALTER TABLE {$NAMESPACE}_repository.repository_pushlog
5+
ADD KEY `key_event` (pushEventPHID);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
$conn_w = id(new PhabricatorRepository())->establishConnection('w');
4+
5+
echo "Adding transaction log event groups...\n";
6+
7+
$logs = queryfx_all(
8+
$conn_w,
9+
'SELECT * FROM %T GROUP BY transactionKey ORDER BY id ASC',
10+
'repository_pushlog');
11+
foreach ($logs as $log) {
12+
$id = $log['id'];
13+
echo "Migrating log {$id}...\n";
14+
if ($log['pushEventPHID']) {
15+
continue;
16+
}
17+
18+
$event_phid = id(new PhabricatorRepositoryPushEvent())->generatePHID();
19+
20+
queryfx(
21+
$conn_w,
22+
'INSERT INTO %T (phid, repositoryPHID, epoch, pusherPHID, remoteAddress,
23+
remoteProtocol, rejectCode, rejectDetails)
24+
VALUES (%s, %s, %d, %s, %d, %s, %d, %s)',
25+
'repository_pushevent',
26+
$event_phid,
27+
$log['repositoryPHID'],
28+
$log['epoch'],
29+
$log['pusherPHID'],
30+
$log['remoteAddress'],
31+
$log['remoteProtocol'],
32+
$log['rejectCode'],
33+
$log['rejectDetails']);
34+
35+
queryfx(
36+
$conn_w,
37+
'UPDATE %T SET pushEventPHID = %s WHERE transactionKey = %s',
38+
'repository_pushlog',
39+
$event_phid,
40+
$log['transactionKey']);
41+
}
42+
43+
echo "Done.\n";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
ALTER TABLE {$NAMESPACE}_repository.repository_pushlog
2+
DROP remoteAddress;
3+
4+
ALTER TABLE {$NAMESPACE}_repository.repository_pushlog
5+
DROP remoteProtocol;
6+
7+
ALTER TABLE {$NAMESPACE}_repository.repository_pushlog
8+
DROP transactionKey;
9+
10+
ALTER TABLE {$NAMESPACE}_repository.repository_pushlog
11+
DROP rejectCode;
12+
13+
ALTER TABLE {$NAMESPACE}_repository.repository_pushlog
14+
DROP rejectDetails;

src/__phutil_library_map__.php

+10
Original file line numberDiff line numberDiff line change
@@ -1958,11 +1958,14 @@
19581958
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeArcanistProject.php',
19591959
'PhabricatorRepositoryPHIDTypeCommit' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeCommit.php',
19601960
'PhabricatorRepositoryPHIDTypeMirror' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeMirror.php',
1961+
'PhabricatorRepositoryPHIDTypePushEvent' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypePushEvent.php',
19611962
'PhabricatorRepositoryPHIDTypePushLog' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypePushLog.php',
19621963
'PhabricatorRepositoryPHIDTypeRepository' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeRepository.php',
19631964
'PhabricatorRepositoryParsedChange' => 'applications/repository/data/PhabricatorRepositoryParsedChange.php',
19641965
'PhabricatorRepositoryPullEngine' => 'applications/repository/engine/PhabricatorRepositoryPullEngine.php',
19651966
'PhabricatorRepositoryPullLocalDaemon' => 'applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php',
1967+
'PhabricatorRepositoryPushEvent' => 'applications/repository/storage/PhabricatorRepositoryPushEvent.php',
1968+
'PhabricatorRepositoryPushEventQuery' => 'applications/repository/query/PhabricatorRepositoryPushEventQuery.php',
19661969
'PhabricatorRepositoryPushLog' => 'applications/repository/storage/PhabricatorRepositoryPushLog.php',
19671970
'PhabricatorRepositoryPushLogQuery' => 'applications/repository/query/PhabricatorRepositoryPushLogQuery.php',
19681971
'PhabricatorRepositoryPushLogSearchEngine' => 'applications/repository/query/PhabricatorRepositoryPushLogSearchEngine.php',
@@ -4792,11 +4795,18 @@
47924795
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'PhabricatorPHIDType',
47934796
'PhabricatorRepositoryPHIDTypeCommit' => 'PhabricatorPHIDType',
47944797
'PhabricatorRepositoryPHIDTypeMirror' => 'PhabricatorPHIDType',
4798+
'PhabricatorRepositoryPHIDTypePushEvent' => 'PhabricatorPHIDType',
47954799
'PhabricatorRepositoryPHIDTypePushLog' => 'PhabricatorPHIDType',
47964800
'PhabricatorRepositoryPHIDTypeRepository' => 'PhabricatorPHIDType',
47974801
'PhabricatorRepositoryParsedChange' => 'Phobject',
47984802
'PhabricatorRepositoryPullEngine' => 'PhabricatorRepositoryEngine',
47994803
'PhabricatorRepositoryPullLocalDaemon' => 'PhabricatorDaemon',
4804+
'PhabricatorRepositoryPushEvent' =>
4805+
array(
4806+
0 => 'PhabricatorRepositoryDAO',
4807+
1 => 'PhabricatorPolicyInterface',
4808+
),
4809+
'PhabricatorRepositoryPushEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
48004810
'PhabricatorRepositoryPushLog' =>
48014811
array(
48024812
0 => 'PhabricatorRepositoryDAO',

src/applications/diffusion/controller/DiffusionPushLogListController.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,15 @@ public function renderResultsList(
5252
// Reveal this if it's valid and the user can edit the repository.
5353
$remote_addr = '-';
5454
if (isset($editable_repos[$log->getRepositoryPHID()])) {
55-
$remote_long = $log->getRemoteAddress();
55+
$remote_long = $log->getPushEvent()->getRemoteAddress();
5656
if ($remote_long) {
5757
$remote_addr = long2ip($remote_long);
5858
}
5959
}
6060

6161
$callsign = $log->getRepository()->getCallsign();
6262
$rows[] = array(
63+
$log->getPushEvent()->getID(),
6364
phutil_tag(
6465
'a',
6566
array(
@@ -68,7 +69,7 @@ public function renderResultsList(
6869
$callsign),
6970
$this->getHandle($log->getPusherPHID())->renderLink(),
7071
$remote_addr,
71-
$log->getRemoteProtocol(),
72+
$log->getPushEvent()->getRemoteProtocol(),
7273
$log->getRefType(),
7374
$log->getRefName(),
7475
phutil_tag(
@@ -86,14 +87,15 @@ public function renderResultsList(
8687

8788
// TODO: Make these human-readable.
8889
$log->getChangeFlags(),
89-
$log->getRejectCode(),
90+
$log->getPushEvent()->getRejectCode(),
9091
phabricator_datetime($log->getEpoch(), $viewer),
9192
);
9293
}
9394

9495
$table = id(new AphrontTableView($rows))
9596
->setHeaders(
9697
array(
98+
pht('Push'),
9799
pht('Repository'),
98100
pht('Pusher'),
99101
pht('From'),
@@ -113,6 +115,7 @@ public function renderResultsList(
113115
'',
114116
'',
115117
'',
118+
'',
116119
'wide',
117120
'n',
118121
'n',

src/applications/diffusion/engine/DiffusionCommitHookEngine.php

+28-37
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ final class DiffusionCommitHookEngine extends Phobject {
3030
private $gitCommits = array();
3131

3232
private $heraldViewerProjects;
33+
private $rejectCode = PhabricatorRepositoryPushLog::REJECT_BROKEN;
34+
private $rejectDetails;
3335

3436

3537
/* -( Config )------------------------------------------------------------- */
@@ -62,14 +64,6 @@ private function getRemoteAddressForLog() {
6264
return $remote_address;
6365
}
6466

65-
private function getTransactionKey() {
66-
if (!$this->transactionKey) {
67-
$entropy = Filesystem::readRandomBytes(64);
68-
$this->transactionKey = PhabricatorHash::digestForIndex($entropy);
69-
}
70-
return $this->transactionKey;
71-
}
72-
7367
public function setSubversionTransactionInfo($transaction, $repository) {
7468
$this->subversionTransaction = $transaction;
7569
$this->subversionRepository = $repository;
@@ -137,10 +131,7 @@ public function execute() {
137131
} catch (DiffusionCommitHookRejectException $ex) {
138132
// If we're rejecting dangerous changes, flag everything that we've
139133
// seen as rejected so it's clear that none of it was accepted.
140-
foreach ($all_updates as $update) {
141-
$update->setRejectCode(
142-
PhabricatorRepositoryPushLog::REJECT_DANGEROUS);
143-
}
134+
$this->rejectCode = PhabricatorRepositoryPushLog::REJECT_DANGEROUS;
144135
throw $ex;
145136
}
146137

@@ -156,19 +147,26 @@ public function execute() {
156147

157148
// If we make it this far, we're accepting these changes. Mark all the
158149
// logs as accepted.
159-
foreach ($all_updates as $update) {
160-
$update->setRejectCode(PhabricatorRepositoryPushLog::REJECT_ACCEPT);
161-
}
150+
$this->rejectCode = PhabricatorRepositoryPushLog::REJECT_ACCEPT;
162151
} catch (Exception $ex) {
163152
// We'll throw this again in a minute, but we want to save all the logs
164153
// first.
165154
$caught = $ex;
166155
}
167156

168157
// Save all the logs no matter what the outcome was.
169-
foreach ($all_updates as $update) {
170-
$update->save();
171-
}
158+
$event = $this->newPushEvent();
159+
160+
$event->setRejectCode($this->rejectCode);
161+
$event->setRejectDetails($this->rejectDetails);
162+
163+
$event->openTransaction();
164+
$event->save();
165+
foreach ($all_updates as $update) {
166+
$update->setPushEventPHID($event->getPHID());
167+
$update->save();
168+
}
169+
$event->saveTransaction();
172170

173171
if ($caught) {
174172
throw $caught;
@@ -296,10 +294,8 @@ private function applyHeraldRules(
296294
}
297295

298296
if ($blocking_effect) {
299-
foreach ($all_updates as $update) {
300-
$update->setRejectCode(PhabricatorRepositoryPushLog::REJECT_HERALD);
301-
$update->setRejectDetails($blocking_effect->getRulePHID());
302-
}
297+
$this->rejectCode = PhabricatorRepositoryPushLog::REJECT_HERALD;
298+
$this->rejectDetails = $blocking_effect->getRulePHID();
303299

304300
$message = $blocking_effect->getTarget();
305301
if (!strlen($message)) {
@@ -596,12 +592,8 @@ private function applyCustomHooks(array $updates) {
596592
continue;
597593
}
598594

599-
// Mark everything as rejected by this hook.
600-
foreach ($updates as $update) {
601-
$update->setRejectCode(
602-
PhabricatorRepositoryPushLog::REJECT_EXTERNAL);
603-
$update->setRejectDetails(basename($hook));
604-
}
595+
$this->rejectCode = PhabricatorRepositoryPushLog::REJECT_EXTERNAL;
596+
$this->rejectDetails = basename($hook);
605597

606598
throw new DiffusionCommitHookRejectException(
607599
pht(
@@ -983,24 +975,23 @@ private function findSubversionContentUpdates(array $ref_updates) {
983975

984976

985977
private function newPushLog() {
986-
// NOTE: By default, we create these with REJECT_BROKEN as the reject
987-
// code. This indicates a broken hook, and covers the case where we
988-
// encounter some unexpected exception and consequently reject the changes.
989-
990978
// NOTE: We generate PHIDs up front so the Herald transcripts can pick them
991979
// up.
992980
$phid = id(new PhabricatorRepositoryPushLog())->generatePHID();
993981

994982
return PhabricatorRepositoryPushLog::initializeNewLog($this->getViewer())
995983
->setPHID($phid)
996-
->attachRepository($this->getRepository())
997984
->setRepositoryPHID($this->getRepository()->getPHID())
998-
->setEpoch(time())
985+
->setEpoch(time());
986+
}
987+
988+
private function newPushEvent() {
989+
$viewer = $this->getViewer();
990+
return PhabricatorRepositoryPushEvent::initializeNewEvent($viewer)
991+
->setRepositoryPHID($this->getRepository()->getPHID())
999992
->setRemoteAddress($this->getRemoteAddressForLog())
1000993
->setRemoteProtocol($this->getRemoteProtocol())
1001-
->setTransactionKey($this->getTransactionKey())
1002-
->setRejectCode(PhabricatorRepositoryPushLog::REJECT_BROKEN)
1003-
->setRejectDetails(null);
994+
->setEpoch(time());
1004995
}
1005996

1006997
public function loadChangesetsForCommit($identifier) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
final class PhabricatorRepositoryPHIDTypePushEvent
4+
extends PhabricatorPHIDType {
5+
6+
const TYPECONST = 'PSHE';
7+
8+
public function getTypeConstant() {
9+
return self::TYPECONST;
10+
}
11+
12+
public function getTypeName() {
13+
return pht('Push Event');
14+
}
15+
16+
public function newObject() {
17+
return new PhabricatorRepositoryPushEvent();
18+
}
19+
20+
protected function buildQueryForObjects(
21+
PhabricatorObjectQuery $query,
22+
array $phids) {
23+
24+
return id(new PhabricatorRepositoryPushEventQuery())
25+
->withPHIDs($phids);
26+
}
27+
28+
public function loadHandles(
29+
PhabricatorHandleQuery $query,
30+
array $handles,
31+
array $objects) {
32+
33+
foreach ($handles as $phid => $handle) {
34+
$event = $objects[$phid];
35+
36+
$handle->setName(pht('Push Event %d', $event->getID()));
37+
}
38+
}
39+
40+
}

0 commit comments

Comments
 (0)