Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-08-18 15:11:07 +00:00
parent fba0187263
commit 07268180a2
38 changed files with 204 additions and 1919 deletions

View file

@ -127,20 +127,18 @@ export default {
:config="$options.integrationViewConfigs[view.name]"
/>
</div>
<div class="col-lg-4 profile-settings-sidebar"></div>
<div class="col-lg-8">
<div class="form-group">
<gl-button
category="primary"
variant="confirm"
name="commit"
type="submit"
:disabled="!isSubmitEnabled"
:value="$options.i18n.saveChanges"
>
{{ $options.i18n.saveChanges }}
</gl-button>
</div>
<div class="col-sm-12">
<hr />
<gl-button
category="primary"
variant="confirm"
name="commit"
type="submit"
:disabled="!isSubmitEnabled"
:value="$options.i18n.saveChanges"
>
{{ $options.i18n.saveChanges }}
</gl-button>
</div>
</div>
</template>

View file

@ -53,6 +53,7 @@ module Ci
end
has_one :runner_session, class_name: 'Ci::BuildRunnerSession', validate: true, inverse_of: :build
has_one :trace_metadata, class_name: 'Ci::BuildTraceMetadata', inverse_of: :build
accepts_nested_attributes_for :runner_session, update_only: true
accepts_nested_attributes_for :job_variables

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
module Ci
class BuildTraceMetadata < Ci::ApplicationRecord
self.table_name = 'ci_build_trace_metadata'
self.primary_key = :build_id
belongs_to :build, class_name: 'Ci::Build'
belongs_to :trace_artifact, class_name: 'Ci::JobArtifact'
validates :build, presence: true
end
end

View file

@ -24,16 +24,8 @@ class UserInteractedProject < ApplicationRecord
}
cached_exists?(**attributes) do
transaction(requires_new: true) do
where(attributes).select(1).first || create!(attributes)
true # not caching the whole record here for now
rescue ActiveRecord::RecordNotUnique
# Note, above queries are not atomic and prone
# to race conditions (similar like #find_or_create!).
# In the case where we hit this, the record we want
# already exists - shortcut and return.
true
end
where(attributes).exists? || UserInteractedProject.insert_all([attributes], unique_by: %w(project_id user_id))
true
end
end

View file

@ -122,10 +122,9 @@
= f.check_box :include_private_contributions, label: s_('Profiles|Include private contributions on my profile'), wrapper_class: 'mb-2', inline: true
.help-block
= s_("Profiles|Choose to show contributions of private projects on your public profile without any project, repository or organization information")
.row.gl-justify-content-end.gl-mt-5
.col-lg-8.gl-display-flex
= f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm gl-mr-3'
= link_to _("Cancel"), user_path(current_user), class: 'gl-button btn btn-default btn-cancel'
%hr
= f.submit s_("Profiles|Update profile settings"), class: 'gl-button btn btn-confirm gl-mr-3'
= link_to _("Cancel"), user_path(current_user), class: 'gl-button btn btn-default btn-cancel'
.modal.modal-profile-crop{ data: { cropper_css_path: ActionController::Base.helpers.stylesheet_path('lazy_bundles/cropper.css') } }
.modal-dialog

View file

@ -0,0 +1,32 @@
# frozen_string_literal: true
class CreateCiBuildTraceMetadata < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
def up
with_lock_retries do
create_table :ci_build_trace_metadata, id: false, if_not_exists: true do |t|
t.references :build,
index: false,
primary_key: true,
default: nil,
foreign_key: { to_table: :ci_builds, on_delete: :cascade },
type: :bigint,
null: false
t.bigint :trace_artifact_id
t.integer :archival_attempts, default: 0, null: false, limit: 2
t.binary :checksum
t.binary :remote_checksum
t.index :trace_artifact_id
end
end
end
def down
with_lock_retries do
drop_table :ci_build_trace_metadata, if_exists: true
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
class AddForeignKeyFromCiBuildMetadataToCiJobArtifacts < ActiveRecord::Migration[6.1]
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def up
add_concurrent_foreign_key :ci_build_trace_metadata,
:ci_job_artifacts,
column: :trace_artifact_id,
on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key :ci_build_trace_metadata, column: :trace_artifact_id
end
end
end

View file

@ -0,0 +1 @@
78ea79c2157acb8a0b29afb4d2f3de6965fb0ea885b5d5f939f22ccda1d53b1e

View file

@ -0,0 +1 @@
e301e1be82c96e62bba0f958c54dda4633b28553246d4c576d6de33cd33e0a50

View file

@ -10575,6 +10575,14 @@ CREATE SEQUENCE ci_build_trace_chunks_id_seq
ALTER SEQUENCE ci_build_trace_chunks_id_seq OWNED BY ci_build_trace_chunks.id;
CREATE TABLE ci_build_trace_metadata (
build_id bigint NOT NULL,
trace_artifact_id bigint,
archival_attempts smallint DEFAULT 0 NOT NULL,
checksum bytea,
remote_checksum bytea
);
CREATE TABLE ci_builds (
id integer NOT NULL,
status character varying,
@ -21364,6 +21372,9 @@ ALTER TABLE ONLY ci_build_report_results
ALTER TABLE ONLY ci_build_trace_chunks
ADD CONSTRAINT ci_build_trace_chunks_pkey PRIMARY KEY (id);
ALTER TABLE ONLY ci_build_trace_metadata
ADD CONSTRAINT ci_build_trace_metadata_pkey PRIMARY KEY (build_id);
ALTER TABLE ONLY dep_ci_build_trace_sections
ADD CONSTRAINT ci_build_trace_sections_pkey PRIMARY KEY (build_id, section_name_id);
@ -23322,6 +23333,8 @@ CREATE INDEX index_ci_build_report_results_on_project_id ON ci_build_report_resu
CREATE UNIQUE INDEX index_ci_build_trace_chunks_on_build_id_and_chunk_index ON ci_build_trace_chunks USING btree (build_id, chunk_index);
CREATE INDEX index_ci_build_trace_metadata_on_trace_artifact_id ON ci_build_trace_metadata USING btree (trace_artifact_id);
CREATE UNIQUE INDEX index_ci_builds_metadata_on_build_id ON ci_builds_metadata USING btree (build_id);
CREATE INDEX index_ci_builds_metadata_on_build_id_and_has_exposed_artifacts ON ci_builds_metadata USING btree (build_id) WHERE (has_exposed_artifacts IS TRUE);
@ -26200,6 +26213,9 @@ ALTER TABLE ONLY epics
ALTER TABLE ONLY geo_container_repository_updated_events
ADD CONSTRAINT fk_212c89c706 FOREIGN KEY (container_repository_id) REFERENCES container_repositories(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_build_trace_metadata
ADD CONSTRAINT fk_21d25cac1a FOREIGN KEY (trace_artifact_id) REFERENCES ci_job_artifacts(id) ON DELETE CASCADE;
ALTER TABLE ONLY users_star_projects
ADD CONSTRAINT fk_22cd27ddfc FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@ -28027,6 +28043,9 @@ ALTER TABLE ONLY analytics_cycle_analytics_group_stages
ALTER TABLE ONLY metrics_dashboard_annotations
ADD CONSTRAINT fk_rails_aeb11a7643 FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_build_trace_metadata
ADD CONSTRAINT fk_rails_aebc78111f FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
ALTER TABLE ONLY bulk_import_trackers
ADD CONSTRAINT fk_rails_aed566d3f3 FOREIGN KEY (bulk_import_entity_id) REFERENCES bulk_import_entities(id) ON DELETE CASCADE;

View file

@ -41,7 +41,7 @@ To enable or disable GitLab CI/CD pipelines in your project:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > General**.
1. Expand **Visibility, project features, permissions**.
1. In the **Repository** section, turn on or off **Pipelines** as required.
1. In the **Repository** section, turn on or off **CI/CD** as required.
**Project visibility** also affects pipeline visibility. If set to:

View file

@ -386,6 +386,6 @@ If you're unsure if it's secure or not, you need to ask security experts for cro
After your CI/CD template MR is created and labeled with `ci::templates`, DangerBot
suggests one reviewer and one maintainer that can review your code. When your merge
request is ready for review, please `@mention` the reviewer and ask them to review
your CI/CD template changes. See details in the merge request that added
request is ready for review, please [mention](../../user/project/issues/issue_data_and_actions.md#mentions)
the reviewer and ask them to review your CI/CD template changes. See details in the merge request that added
[a DangerBot task for CI/CD template MRs](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44688).

View file

@ -129,8 +129,8 @@ The general flow of contributing to GitLab is:
1. In the merge request's description:
- Ensure you provide complete and accurate information.
- Review the provided checklist.
1. Assign the merge request (if possible) to, or `@mention`, one of the
[code owners](../../user/project/code_owners.md) for the relevant project,
1. Assign the merge request (if possible) to, or [mention](../../user/project/issues/issue_data_and_actions.md#mentions),
one of the [code owners](../../user/project/code_owners.md) for the relevant project,
and explain that you are ready for review.
When you submit code to GitLab, we really want it to get merged! However, we always review
@ -167,18 +167,18 @@ GitLab will do its best to review community contributions as quickly as possible
appointed developers review community contributions daily. Look at the
[team page](https://about.gitlab.com/company/team/) for the merge request coach who specializes in
the type of code you have written and mention them in the merge request. For example, if you have
written some front-end code, you should `@mention` the frontend merge request coach. If
your code has multiple disciplines, you may `@mention` multiple merge request coaches.
written some front-end code, you should mention the frontend merge request coach. If
your code has multiple disciplines, you may mention multiple merge request coaches.
GitLab receives a lot of community contributions. If your code has not been reviewed within two
working days of its initial submission, feel free to `@mention` all merge request coaches with
working days of its initial submission, feel free to mention all merge request coaches with
`@gitlab-org/coaches` to get their attention.
When submitting code to GitLab, you may feel that your contribution requires the aid of an external
library. If your code includes an external library, please provide a link to the library, as well as
reasons for including it.
`@mention` a maintainer in merge requests that contain:
Mention a maintainer in merge requests that contain:
- More than 500 changes.
- Any major [breaking changes](#breaking-changes).

View file

@ -17,6 +17,12 @@ For guidance not on this page, we defer to these style guides:
<!-- vale off -->
<!-- markdownlint-disable -->
## @mention
Try to avoid. Say "mention" instead, and consider linking to the
[mentions topic](../../../user/project/issues/issue_data_and_actions.md#mentions).
Don't use `code formatting`.
## above
Try to avoid extra words when referring to an example or table in a documentation page, but if required, use **previously** instead.

View file

@ -250,6 +250,10 @@ hub_docker_quota_check:
TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq --raw-output .token) && curl --head --header "Authorization: Bearer $TOKEN" "https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest" 2>&1
```
## Use the NPM Dependency Proxy for NPM packages
For information on this, see [Dependency Proxy](../npm_registry/#dependency-proxy).
## Troubleshooting
### Dependency Proxy Connection Failure

View file

@ -601,3 +601,8 @@ The GitLab npm repository supports the following commands for the npm CLI (`npm`
- `npm view`: Show package metadata.
- `yarn add`: Install an npm package.
- `yarn update`: Update your dependencies.
## Dependency Proxy
The NPM Dependency Proxy for NPM packages isn't available. For more information, see
[this epic](https://gitlab.com/groups/gitlab-org/-/epics/3608).

View file

@ -143,7 +143,7 @@ For each project and group you can select one of the following levels:
|:------------|:------------|
| Global | Your global settings apply. |
| Watch | Receive notifications for any activity. |
| On mention | Receive notifications when `@mentioned` in comments. |
| On mention | Receive notifications when [mentioned](../project/issues/issue_data_and_actions.md#mentions) in a comment. |
| Participate | Receive notifications for threads you have participated in. |
| Disabled | Turns off notifications. |
| Custom | Receive notifications for custom selected events. |
@ -278,7 +278,7 @@ The participants are:
- Authors of the design (can be multiple people if different authors have uploaded different versions of the design).
- Authors of comments on the design.
- Anyone that is `@mentioned` in a comment on the design.
- Anyone that is [mentioned](../project/issues/issue_data_and_actions.md#mentions) in a comment on the design.
## Opt out of all GitLab emails

View file

@ -199,7 +199,7 @@ You can mention a user or a group present in your GitLab instance with `@usernam
unless they have disabled all [notifications](#notifications) in their user settings.
This is controlled in the [notification settings](../../profile/notifications.md).
Mentions for yourself (the current logged in user) are highlighted
Mentions for yourself (the user currently signed in) are highlighted
in a different color, which allows you to quickly see which comments involve you.
Avoid mentioning `@all` in issues and merge requests, as it sends an email notification

View file

@ -234,16 +234,29 @@ different branch.
> - Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/18059) in [GitLab Free](https://about.gitlab.com/pricing/) 10.7.
> - Support for pasting images [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22822) in [GitLab Free](https://about.gitlab.com/pricing/) 13.1.
> - Side-by-side Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68274) in [GitLab Free](https://about.gitlab.com/pricing/) 14.3
When you edit Markdown files in the Web IDE, you can preview your changes by
clicking the **Preview Markdown** tab above the file editor. The Markdown preview
supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown).
To edit Markdown files in the Web IDE:
You can also upload any local images by pasting them directly in the Markdown file.
1. Go to your repository, and navigate to the Markdown page you want to edit.
1. Select **Edit in Web IDE**, and GitLab loads the page in a tab in the editor.
1. Make your changes to the file. GitLab supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown).
1. When your changes are complete, select **Commit** in the left sidebar.
1. Add a commit message, select the branch you want to commit to, and select **Commit**.
When editing, you can upload local images by pasting them directly in the Markdown file.
The image is uploaded to the same directory and is named `image.png` by default.
If another file already exists with the same name, a numeric suffix is automatically
added to the filename.
There are two ways to preview Markdown content in the Web IDE:
1. At the top of the file's tab, select **Preview Markdown** to preview the formatting
in your file. You can't edit the file in this view.
1. To add more changes to the file, select **Edit**.
1. Right-click or use the keyboard shortcut `Command/Control + Shift + P` and
select **Preview Markdown** to toggle a live Markdown preview panel.
## Live Preview
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19764) in [GitLab Free](https://about.gitlab.com/pricing/) 11.2.

View file

@ -31,9 +31,9 @@ Many to-do items are created automatically.
A to-do item is added to your To-Do List when:
- An issue or merge request is assigned to you.
- You're `@mentioned` in the description or comment of an issue, merge request,
or epic.
- You are `@mentioned` in a comment on a commit or design.
- You're [mentioned](project/issues/issue_data_and_actions.md#mentions) in the description or
comment of an issue, merge request, or epic.
- You are mentioned in a comment on a commit or design.
- The CI/CD pipeline for your merge request fails.
- An open merge request cannot be merged due to conflict, and one of the
following is true:

View file

@ -108,6 +108,11 @@ module Gitlab
# Configures proxying of requests.
def self.configure_proxy(proxy = ConnectionProxy.new(hosts))
ActiveRecord::Base.load_balancing_proxy = proxy
# Populate service discovery immediately if it is configured
if service_discovery_enabled?
ServiceDiscovery.new(service_discovery_configuration).perform_service_discovery
end
end
def self.active_record_models

View file

@ -63,18 +63,14 @@ module Gitlab
end
def start
# We run service discovery once in the current thread so that the application's main thread
# does not race this thread to use the results of initial service discovery.
next_sleep_duration = perform_service_discovery
Thread.new do
loop do
next_sleep_duration = perform_service_discovery
# We slightly randomize the sleep() interval. This should reduce
# the likelihood of _all_ processes refreshing at the same time,
# possibly putting unnecessary pressure on the DNS server.
sleep(next_sleep_duration + rand(MAX_SLEEP_ADJUSTMENT))
next_sleep_duration = perform_service_discovery
end
end
end

View file

@ -57,16 +57,13 @@ RSpec.describe Gitlab::Database::LoadBalancing::ServiceDiscovery do
.and_yield
end
it 'runs service discovery once before starting the worker thread' do
expect(service).to receive(:perform_service_discovery).ordered.and_return(5)
it 'starts service discovery in a new thread' do
expect(Thread).to receive(:new).ordered.and_call_original # Thread starts
expect(service).to receive(:perform_service_discovery).ordered.and_return(5)
expect(service).to receive(:rand).ordered.and_return(2)
expect(service).to receive(:sleep).ordered.with(7) # Sleep runs after thread starts
expect(service).to receive(:perform_service_discovery).ordered.and_return(1)
service.start.join
end
end

View file

@ -212,6 +212,21 @@ RSpec.describe Gitlab::Database::LoadBalancing do
expect(ActiveRecord::Base).to have_received(:load_balancing_proxy=)
.with(Gitlab::Database::LoadBalancing::ConnectionProxy)
end
context 'when service discovery is enabled' do
let(:service_discovery) { double(Gitlab::Database::LoadBalancing::ServiceDiscovery) }
it 'runs initial service discovery when configuring the connection proxy' do
allow(described_class)
.to receive(:configuration)
.and_return('discover' => { 'record' => 'foo' })
expect(Gitlab::Database::LoadBalancing::ServiceDiscovery).to receive(:new).and_return(service_discovery)
expect(service_discovery).to receive(:perform_service_discovery)
described_class.configure_proxy
end
end
end
describe '.active_record_models' do

View file

@ -28,6 +28,7 @@ RSpec.describe Ci::Build do
it { is_expected.to have_one(:deployment) }
it { is_expected.to have_one(:runner_session) }
it { is_expected.to have_one(:trace_metadata) }
it { is_expected.to validate_presence_of(:ref) }

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::BuildTraceMetadata do
it { is_expected.to belong_to(:build) }
it { is_expected.to belong_to(:trace_artifact) }
it { is_expected.to validate_presence_of(:build) }
end

View file

@ -60,7 +60,7 @@ RSpec.describe Ci::RetryBuildService do
artifacts_file artifacts_metadata artifacts_size commands
resource resource_group_id processed security_scans author
pipeline_id report_results pending_state pages_deployments
queuing_entry runtime_metadata].freeze
queuing_entry runtime_metadata trace_metadata].freeze
shared_examples 'build duplication' do
let_it_be(:another_pipeline) { create(:ci_empty_pipeline, project: project) }

View file

@ -1,83 +0,0 @@
workflow:
rules: &workflow_rules
# For merge requests, create a pipeline.
- if: '$CI_MERGE_REQUEST_IID'
# For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
# For tags, create a pipeline.
- if: '$CI_COMMIT_TAG'
# For stable branches, create a pipeline.
- if: '$CI_COMMIT_BRANCH =~ /^[\d-]+-stable$/'
default:
image: golang:1.16
tags:
- gitlab-org
# Disable DIND for SAST because we need to execute a before_script in the gosec-sast job
variables:
SAST_DISABLE_DIND: "true"
verify:
script:
- make verify
changelog:
script:
- _support/check_changelog.sh
rules:
- if: '$CI_MERGE_REQUEST_IID'
.test:
services:
- name: registry.gitlab.com/gitlab-org/build/cng/gitaly:latest
# Disable the hooks so we don't have to stub the GitLab API
command: ["/usr/bin/env", "GITALY_TESTING_NO_GIT_HOOKS=1", "/scripts/process-wrapper"]
alias: gitaly
variables:
GITALY_ADDRESS: "tcp://gitaly:8075"
script:
- go version
- apt-get update && apt-get -y install libimage-exiftool-perl
- make test
test using go 1.15:
extends: .test
image: golang:1.15
test using go 1.16:
extends: .test
image: golang:1.16
test:release:
rules:
- if: '$CI_COMMIT_TAG'
script:
- git describe --exact-match
include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
gosec-sast:
before_script:
- apk add make
- make install
rules: *workflow_rules
gemnasium-dependency_scanning:
rules: *workflow_rules
secret_detection:
rules: *workflow_rules
code_navigation:
image: golang:latest
allow_failure: true
script:
- go get github.com/sourcegraph/lsif-go/cmd/lsif-go
- lsif-go
artifacts:
reports:
lsif: dump.lsif

View file

@ -1 +0,0 @@
* @jacobvosmaer-gitlab @nick.thomas @nolith @patrickbajao

File diff suppressed because it is too large Load diff

View file

@ -1,46 +0,0 @@
## Contributing
Thank you for your interest in contributing to this GitLab project! We welcome
all contributions. By participating in this project, you agree to abide by the
[code of conduct](#code-of-conduct).
## Contributor license agreement
By submitting code as an individual you agree to the [individual contributor
license agreement][individual-agreement].
By submitting code as an entity you agree to the [corporate contributor license
agreement][corporate-agreement].
## Code of conduct
As contributors and maintainers of this project, we pledge to respect all people
who contribute through reporting issues, posting feature requests, updating
documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual
language or imagery, derogatory comments or personal attacks, trolling, public
or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct. Project maintainers who do not follow the
Code of Conduct may be removed from the project team.
This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior can be
reported by emailing contact@gitlab.com.
This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant], version 1.1.0,
available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/).
[contributor-covenant]: http://contributor-covenant.org
[individual-agreement]: https://docs.gitlab.com/ee/legal/individual_contributor_license_agreement.html
[corporate-agreement]: https://docs.gitlab.com/ee/legal/corporate_contributor_license_agreement.html

View file

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2015-2017 GitLab B.V.
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.

View file

@ -2,9 +2,6 @@ PREFIX=/usr/local
PKG := gitlab.com/gitlab-org/gitlab/workhorse
BUILD_DIR ?= $(CURDIR)
TARGET_DIR ?= $(BUILD_DIR)/_build
TARGET_SETUP := $(TARGET_DIR)/.ok
BIN_BUILD_DIR := $(TARGET_DIR)/bin
COVERAGE_DIR := $(TARGET_DIR)/cover
VERSION_STRING := $(shell git describe)
ifeq ($(strip $(VERSION_STRING)),)
VERSION_STRING := v$(shell cat VERSION)
@ -32,53 +29,40 @@ endef
.PHONY: all
all: clean-build $(EXE_ALL)
$(TARGET_SETUP):
$(call message,"Setting up target directory")
rm -rf "$(TARGET_DIR)"
mkdir -p "$(TARGET_DIR)"
touch "$(TARGET_SETUP)"
.PHONY: gitlab-resize-image
gitlab-resize-image: $(TARGET_SETUP)
gitlab-resize-image:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
.PHONY: gitlab-zip-cat
gitlab-zip-cat: $(TARGET_SETUP)
gitlab-zip-cat:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
.PHONY: gitlab-zip-metadata
gitlab-zip-metadata: $(TARGET_SETUP)
gitlab-zip-metadata:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)/cmd/$@
.PHONY: gitlab-workhorse
gitlab-workhorse: $(TARGET_SETUP)
gitlab-workhorse:
$(call message,Building $@)
$(GOBUILD) -tags "$(BUILD_TAGS)" -o $(BUILD_DIR)/$@ $(PKG)
.PHONY: install
install: $(EXE_ALL)
install: $(EXE_ALL)
$(call message,$@)
mkdir -p $(DESTDIR)$(PREFIX)/bin/
cd $(BUILD_DIR) && $(INSTALL) $(EXE_ALL) $(DESTDIR)$(PREFIX)/bin/
.PHONY: test
test: $(TARGET_SETUP) prepare-tests
test: prepare-tests
$(call message,$@)
@go test -tags "$(BUILD_TAGS)" ./...
@echo SUCCESS
.PHONY: coverage
coverage: $(TARGET_SETUP) prepare-tests
$(call message,$@)
@go test -tags "$(BUILD_TAGS)" -cover -coverprofile=test.coverage ./...
go tool cover -html=test.coverage -o coverage.html
rm -f test.coverage
.PHONY: clean
clean: clean-workhorse clean-build
clean: clean-workhorse clean-build
$(call message,$@)
rm -rf testdata/data testdata/scratch
@ -87,20 +71,6 @@ clean-workhorse:
$(call message,$@)
rm -f $(EXE_ALL)
.PHONY: check-version
check-version:
@test -n "$(VERSION)" || (echo "VERSION not set." ; exit 1)
.PHONY: tag
tag: check-version
$(call message,$@)
sh _support/tag.sh "$(VERSION)"
.PHONY: signed_tag
signed_tag: check-version
$(call message,$@)
TAG_OPTS=-s sh _support/tag.sh "$(VERSION)"
.PHONY: clean-build
clean-build:
$(call message,$@)
@ -121,18 +91,18 @@ testdata/scratch:
verify: lint vet detect-context detect-assert check-formatting staticcheck deps-check
.PHONY: lint
lint: $(TARGET_SETUP)
lint:
$(call message,Verify: $@)
go install golang.org/x/lint/golint
@_support/lint.sh ./...
.PHONY: vet
vet: $(TARGET_SETUP)
vet:
$(call message,Verify: $@)
@go vet ./...
.PHONY: detect-context
detect-context: $(TARGET_SETUP)
detect-context:
$(call message,Verify: $@)
_support/detect-context.sh
@ -142,7 +112,7 @@ detect-assert:
_support/detect-assert.sh
.PHONY: check-formatting
check-formatting: $(TARGET_SETUP) install-goimports
check-formatting: install-goimports
$(call message,Verify: $@)
@_support/fmt.sh check
@ -150,7 +120,7 @@ check-formatting: $(TARGET_SETUP) install-goimports
# Additionally, megacheck will not return failure exit codes unless explicitly told to via the
# `-simple.exit-non-zero` `-unused.exit-non-zero` and `-staticcheck.exit-non-zero` flags
.PHONY: staticcheck
staticcheck: $(TARGET_SETUP)
staticcheck:
$(call message,Verify: $@)
go install honnef.co/go/tools/cmd/staticcheck
@ $(GOBIN)/staticcheck -go $(MINIMUM_SUPPORTED_GO_VERSION) ./...
@ -158,12 +128,12 @@ staticcheck: $(TARGET_SETUP)
# In addition to fixing imports, goimports also formats your code in the same style as gofmt
# so it can be used as a replacement.
.PHONY: fmt
fmt: $(TARGET_SETUP) install-goimports
fmt: install-goimports
$(call message,$@)
@_support/fmt.sh
.PHONY: goimports
install-goimports: $(TARGET_SETUP)
install-goimports:
$(call message,$@)
go install golang.org/x/tools/cmd/goimports

View file

@ -4,154 +4,14 @@
GitLab-Workhorse has the following maintainers:
- Patrick Bajao `@patrickbajao`
- Alessio Caiazza `@nolith`
- Nick Thomas `@nick.thomas`
- Jacob Vosmaer `@jacobvosmaer-gitlab`
- Alessio Caiazza `@nolith`
This list is defined at https://about.gitlab.com/team/.
## Changelog
GitLab-Workhorse keeps a changelog which is generated when a new release
is created. The changelog is generated from entries that are included on each
merge request. To generate an entry on your branch run:
`_support/changelog "Change descriptions"`.
After the merge request is created, the ID of the merge request needs to be set
in the generated file. If you already know the merge request ID, run:
`_support/changelog -m <ID> "Change descriptions"`.
Any new merge request must contain either a new entry or a justification in the
merge request description why no changelog entry is needed.
This authoritative source for this list is https://about.gitlab.com/team/.
## Merging and reviewing contributions
Contributions must be reviewed by at least one Workhorse maintainer.
The final merge must be performed by a maintainer.
## Releases
> Below we describe the legacy release process, from when Workhorse
> had its own repository. These instructions are still useful for
> security backports.
New versions of Workhorse can be released by one of the Workhorse
maintainers. The release process is:
- pick a release branch. For x.y.0, use `master`. For all other
versions (x.y.1, x.y.2 etc.) , use `x-y-stable`. Also see [below](#versioning)
- run `make tag VERSION=x.y.z"` or `make signed_tag VERSION=x.y.z` on the release branch. This will
compile the changelog, bump the VERSION file, and make a tag matching it.
- push the branch and the tag to gitlab.com
- the new version will only be deployed to `gitlab.com` if [`GITLAB_WORKHORSE_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_WORKHORSE_VERSION) is updated accordingly;
if applicable, please remind the person who originally asked for a new release to make this change
(the MR should include a link back to the [version tag](https://gitlab.com/gitlab-org/gitlab-workhorse/-/tags) and a copy of the changelog)
- the person who updates GITLAB_WORKHORSE_VERSION should also run `scripts/update-workhorse` after commiting the new GITLAB_WORKHORSE_VERSION. If they forget they will be reminded by CI.
## Security releases
Workhorse is included in the packages we create for GitLab, and each version of
GitLab specifies the version of Workhorse it uses in the `GITLAB_WORKHORSE_VERSION`
file, so security fixes in Workhorse are tightly coupled to the [general security release](https://about.gitlab.com/handbook/engineering/workflow/#security-issues)
workflow, with some elaborations to account for the changes happening across two
repositories. In particular, the Workhorse maintainer takes responsibility for
creating new patch versions of Workhorse that can be used in the security
release.
As security fixes are backported three releases in addition to master, and
changes need to happen across two repositories, up to eight merge requests, and
four Workhorse releases, can be required to fix a security issue in Workhorse.
This is a lot of overhead, so in general, it is better to fix security issues
without changing Workhorse. Where changes **are** necessary, this section
documents the necessary steps.
If you're working on a security fix in Workhorse, you need two sets of merge
requests:
* The fix itself, in the `gitlab-org/security/gitlab-workhorse` repository
* A merge request to change the version of workhorse included in the GitLab
security release, in the `gitlab-org/security/gitlab` repository.
If the Workhorse maintainer isn't also a GitLab maintainer, reviews will need to
be split across several people. If changes to GitLab **code** are required in
addition to the change of Workhorse version, they both happen in the same merge
request.
Start by creating a single merge request targeting `master` in Workhorse. Ensure
you include a changelog! If code changes are needed in GitLab as well, create a
GitLab merge request targeting `master` at this point, but don't worry about the
`GITLAB_WORKHORSE_VERSION` file yet.
Once the changes have passed review, the Workhorse maintainer will determine the
new versions of Workhorse that will be needed, and communicate that to the
author. To do this, examine the `GITLAB_WORKHORSE_VERSION` file on each GitLab
stable branch; for instance, if the security release consisted of GitLab
versions `12.10.1`, `12.9.2`, `12.8.3`, and `12.7.4`, we would see the following:
```
gitlab$ git fetch security master 12-10-stable-ee 12-9-stable-ee 12-8-stable-ee 12-7-stable-ee`
gitlab$ git show refs/remotes/security/master:GITLAB_WORKHORSE_VERSION
8.30.1
gitlab$ git show refs/remotes/security/12-10-stable-ee:GITLAB_WORKHORSE_VERSION
8.30.1
gitlab$ git show refs/remotes/security/12-9-stable-ee:GITLAB_WORKHORSE_VERSION
8.25.2
gitlab$ git show refs/remotes/security/12-8-stable-ee:GITLAB_WORKHORSE_VERSION
8.21.2
gitlab$ git show refs/remotes/security/12-7-stable-ee:GITLAB_WORKHORSE_VERSION
8.21.2
```
In this example, there are three distinct Workhorse stable branches to be
concerned with, plus Workhorse master: `8-30-stable`, `8-25-stable`, and
`8-21-stable`, and we can predict that we are going to need to create Workhorse
releases `8.30.2`, `8.25.3`, and `8.21.3`.
The author needs to create a merge request targeting each Workhorse stable
branch, and verify that the fix works once backported. They also need to create
(or update, if they already exist) GitLab merge requests, setting the
`GITLAB_WORKHORSE_VERSION` file to the predicted workhorse version, and assign
all the MRs back to the appropriate maintainer(s). The pipeline for the GitLab
MRs will fail until the Workhorse releases have been tagged; you can use the
`=workhorse_branch_name` syntax in the `GITLAB_WORKHORSE_VERSION` file to verify
that the MRs interact as expected, if necessary.
Once all involved maintainers are happy with the overall change, the Workhorse
maintainer will merge each of the Workhorse MRs and generate new Workhorse
releases from the stable branches. The tags will be present on the `security`
mirror and `dev.gitlab.org` **only** at this point.
Once the Workhorse tags exist, the GitLab maintainer ensures that all the GitLab
MRs are green and assigns those MRs on to the release bot.
The release managers merge the GitLab MRs, tag GitLab releases that reference
the new Workhorse tags, and release them in the usual way.
Once the security release is done, the Workhorse maintainer is responsible for
syncing the changes to the `gitlab-org/gitlab-workhorse` repository. Push the
changes to `master`, the new tags, and all the changes to the stable branches.
This process is quite involved, very manual, and extremely error-prone; work is
ongoing on automating it.
## Versioning
Workhorse uses a variation of SemVer. We don't use "normal" SemVer
because we have to be able to integrate into GitLab stable branches.
A version has the format MAJOR.MINOR.PATCH.
- Major and minor releases are tagged on the `master` branch
- If the change is backwards compatible, increment the MINOR counter
- If the change breaks compatibility, increment MAJOR and set MINOR to `0`
- Patch release tags must be made on stable branches
- Only make a patch release when targeting a GitLab stable branch
This means that tags that end in `.0` (e.g. `8.5.0`) must always be on
the master branch, and tags that end in anthing other than `.0` (e.g.
`8.5.2`) must always be on a stable branch.
> The reason we do this is that SemVer suggests something like a
> refactoring constitutes a "patch release", while the GitLab stable
> branch quality standards do not allow for back-porting refactorings
> into a stable branch.

View file

@ -1,243 +0,0 @@
#!/usr/bin/env ruby
#
# Generate a changelog entry file in the correct location.
#
# Automatically stages the file and amends the previous commit if the `--amend`
# argument is used.
#
# Stolen from gitlab-org/gitaly, lifted from gitlab-org/gitlab-ce
require 'optparse'
require 'yaml'
Options = Struct.new(
:amend,
:author,
:dry_run,
:force,
:merge_request,
:title,
:type
)
INVALID_TYPE = -1
class ChangelogOptionParser
Type = Struct.new(:name, :description)
TYPES = [
Type.new('added', 'New feature'),
Type.new('fixed', 'Bug fix'),
Type.new('changed', 'Feature change'),
Type.new('deprecated', 'New deprecation'),
Type.new('removed', 'Feature removal'),
Type.new('security', 'Security fix'),
Type.new('performance', 'Performance improvement'),
Type.new('other', 'Other')
].freeze
TYPES_OFFSET = 1
class << self
def parse(argv)
options = Options.new
parser = OptionParser.new do |opts|
opts.banner = "Usage: #{__FILE__} [options] [title]\n\n"
# Note: We do not provide a shorthand for this in order to match the `git
# commit` interface
opts.on('--amend', 'Amend the previous commit') do |value|
options.amend = value
end
opts.on('-f', '--force', 'Overwrite an existing entry') do |value|
options.force = value
end
opts.on('-m', '--merge-request [integer]', Integer, 'Merge request ID') do |value|
options.merge_request = value
end
opts.on('-n', '--dry-run', "Don't actually write anything, just print") do |value|
options.dry_run = value
end
opts.on('-u', '--git-username', 'Use Git user.name configuration as the author') do |value|
options.author = git_user_name if value
end
opts.on('-t', '--type [string]', String, "The category of the change, valid options are: #{TYPES.map(&:name).join(', ')}") do |value|
options.type = parse_type(value)
end
opts.on('-h', '--help', 'Print help message') do
$stdout.puts opts
exit
end
end
parser.parse!(argv)
# Title is everything that remains, but let's clean it up a bit
options.title = argv.join(' ').strip.squeeze(' ').tr("\r\n", '')
options
end
def read_type
read_type_message
type = TYPES[$stdin.getc.to_i - TYPES_OFFSET]
assert_valid_type!(type)
type.name
end
private
def parse_type(name)
type_found = TYPES.find do |type|
type.name == name
end
type_found ? type_found.name : INVALID_TYPE
end
def read_type_message
$stdout.puts "\n>> Please specify the index for the category of your change:"
TYPES.each_with_index do |type, index|
$stdout.puts "#{index + TYPES_OFFSET}. #{type.description}"
end
$stdout.print "\n?> "
end
def assert_valid_type!(type)
unless type
$stderr.puts "Invalid category index, please select an index between 1 and #{TYPES.length}"
exit 1
end
end
def git_user_name
%x{git config user.name}.strip
end
end
end
class ChangelogEntry
attr_reader :options
def initialize(options)
@options = options
assert_feature_branch!
assert_title!
assert_new_file!
# Read type from $stdin unless is already set
options.type ||= ChangelogOptionParser.read_type
assert_valid_type!
$stdout.puts "\e[32mcreate\e[0m #{file_path}"
$stdout.puts contents
unless options.dry_run
write
amend_commit if options.amend
end
end
private
def contents
yaml_content = YAML.dump(
'title' => title,
'merge_request' => options.merge_request,
'author' => options.author,
'type' => options.type
)
remove_trailing_whitespace(yaml_content)
end
def write
File.write(file_path, contents)
end
def amend_commit
%x{git add #{file_path}}
exec("git commit --amend")
end
def fail_with(message)
$stderr.puts "\e[31merror\e[0m #{message}"
exit 1
end
def assert_feature_branch!
return unless branch_name == 'master'
fail_with "Create a branch first!"
end
def assert_new_file!
return unless File.exist?(file_path)
return if options.force
fail_with "#{file_path} already exists! Use `--force` to overwrite."
end
def assert_title!
return if options.title.length > 0 || options.amend
fail_with "Provide a title for the changelog entry or use `--amend`" \
" to use the title from the previous commit."
end
def assert_valid_type!
return unless options.type && options.type == INVALID_TYPE
fail_with 'Invalid category given!'
end
def title
if options.title.empty?
last_commit_subject
else
options.title
end
end
def last_commit_subject
%x{git log --format="%s" -1}.strip
end
def file_path
File.join(
unreleased_path,
branch_name.gsub(/[^\w-]/, '-') << '.yml'
)
end
def unreleased_path
path = File.join('changelogs', 'unreleased')
path = File.join('ee', path) if ee?
path
end
def ee?
@ee ||= File.exist?(File.expand_path('../CHANGELOG-EE.md', __dir__))
end
def branch_name
@branch_name ||= %x{git symbolic-ref --short HEAD}.strip
end
def remove_trailing_whitespace(yaml_content)
yaml_content.gsub(/ +$/, '')
end
end
if $0 == __FILE__
options = ChangelogOptionParser.parse(ARGV)
ChangelogEntry.new(options)
end
# vim: ft=ruby

View file

@ -1,22 +0,0 @@
#!/bin/sh
set -e
# we skip the changelog check if the merge requet title ends with "NO CHANGELOG"
if echo "$CI_MERGE_REQUEST_TITLE" | grep -q ' NO CHANGELOG$'; then
echo "Changelog not needed"
exit 0
fi
target=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME:-master}
if git diff --name-only "origin/$target" | grep -q '^changelogs/' ; then
echo "Changelog included"
else
echo "Please add a changelog running '_support/changelog'"
echo "or disable this check adding 'NO CHANGELOG' at the end of the merge request title"
echo "/title $CI_MERGE_REQUEST_TITLE NO CHANGELOG"
exit 1
fi

View file

@ -1,75 +0,0 @@
#!/usr/bin/env ruby
# Generates the changelog from the yaml entries in changelogs/unreleased
#
# Lifted form gitlab-org/gitaly
require 'yaml'
require 'fileutils'
class ChangelogEntry
attr_reader :title, :merge_request, :type, :author
def initialize(file_path)
yaml = YAML.safe_load(File.read(file_path))
@title = yaml['title']
@merge_request = yaml['merge_request']
@type = yaml['type']
@author = yaml['author']
end
def to_s
str = ""
str << "- #{title}\n"
str << " https://gitlab.com/gitlab-org/gitlab-workhorse/-/merge_requests/#{merge_request}\n"
str << " Contributed by #{author}\n" if author
str
end
end
ROOT_DIR = File.expand_path('../..', __FILE__)
UNRELEASED_ENTRIES = File.join(ROOT_DIR, 'changelogs', 'unreleased')
CHANGELOG_FILE = File.join(ROOT_DIR, 'CHANGELOG')
def main(version)
entries = []
Dir["#{UNRELEASED_ENTRIES}/*.yml"].each do |yml|
entries << ChangelogEntry.new(yml)
FileUtils.rm(yml)
end
sections = []
types = entries.map(&:type).uniq.sort
types.each do |type|
text = ''
text << "### #{type.capitalize}\n"
entries.each do |e|
next unless e.type == type
text << e.to_s
end
sections << text
end
sections << '- No changes.' if sections.empty?
new_version_entry = ["## v#{version}\n\n", sections.join("\n"), "\n"].join
current_changelog = File.read(CHANGELOG_FILE).lines
header = current_changelog.shift(2)
new_changelog = [header, new_version_entry, current_changelog.join]
File.write(CHANGELOG_FILE, new_changelog.join)
end
unless ARGV.count == 1
warn "Usage: #{$0} VERSION"
warn "Specify version as x.y.z"
abort
end
main(ARGV.first)

View file

@ -1,45 +0,0 @@
set -e
main() {
version=$1
set_version
changelog
git commit VERSION -m "Update VERSION to $version"
tag_name="v${version}"
git tag $TAG_OPTS -m "Version ${version}" -a ${tag_name}
git show ${tag_name}
cat <<'EOF'
Remember to now push your tag, either to gitlab.com (for a
normal release) or dev.gitlab.org (for a security release).
EOF
}
set_version() {
if ! echo "${version}" | grep -q '^[0-9]\+\.[0-9]\+\.[0-9]\+$' ; then
echo "Invalid VERSION: ${version}"
exit 1
fi
if git tag --list | grep -q "^v${version}$" ; then
echo "Tag already exists for ${version}"
exit 1
fi
echo "$version" > VERSION
}
changelog() {
_support/generate_changelog "$version"
git commit CHANGELOG changelogs/unreleased --file - <<EOF
Update CHANGELOG for ${version}
[ci skip]
EOF
}
main "$@"