Replace the current Keep Job Artifacts action with Protect Job Artifacts
<!--IssueSummary start-->
<details>
<summary>
Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards.
</summary>
- [Close this issue](https://contributors.gitlab.com/manage-issue?action=close&projectId=278964&issueIid=21272)
</details>
<!--IssueSummary end-->
### 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 gitlab-ce#38199, 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 gitlab-ce#23777. 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 gitlab-ce#29182. 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"
issue