Replace the current Keep Job Artifacts action with Protect Job Artifacts

Description

The Keep action for job artifacts is not modeled well in the database and its implementation is an obstacle to improving the artifact expiration process.

As described in #38199 (moved), when a user clicks the Keep button on the artifacts pane of a CI Job, the app sets the artifacts_expire_at column to NULL. Meaning, these artifacts never expire. If the expire_at column is already NULL, the Keep button is not shown.

There are a handful of problems caused by implementing Keep artifacts in this way.

  1. It prevents us from implementing artifact expiration policies that aren't based on time. For example, the famous #23777 (moved). If artifacts are set to to expire when they are no longer associated the last-known-good Build, then Keep becomes meaningless. Every Job Artifact has expires_at set to NULL and clicking Keep can't make it more NULL.

  2. You can't unkeep artifacts when you decide you no longer need them. See #29182 (moved). There's no way tell the system to allow them to expire by the currently-in-force expiration policy.

  3. You don't know who kept the artifacts or when. Unlike erased_at and erased_by, we're missing kept_at and kept_by. As an administrator it's important to know who is keeping artifacts beyond the established expiration criteria.

Proposal

Replace the Keep artifacts feature with Protect artifacts

I really like the word Keep as it relates to artifacts, but Unkeep doesn't work for me and Remove is inaccurate. Protect and Unprotect work well together, and are used in other places within GitLab.

Extend the Build model

At a minimum we should add the columns artifacts_protected (bool), artifacts_protected_by (user), artifacts_protected_at (date).

Replace the Keep button with a Protect button

When the Protect button is clicked, provide an Unprotect button, and update the label to say:

The artifacts from this job were protected from removal by @haboustak 6 days ago

Stretch goal: Implement an artifact timeline

It would be ideal to implement artifact events. Each protect/unprotect/erase transition is recorded in a timeline. Example:

  • The artifacts from this job were erased 25 minutes ago.

  • The artifacts from this job were unprotected by @haboustak 2 weeks ago

  • The artifacts from this job were protected from removal by @haboustak 8 months ago

~"feature proposal"

Edited by Mike Haboustak