Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-11-05 00:13:55 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-05 00:13:55 +0300
commit2fdc3eaafbfcaef2dcfea4629be5ec67595e7e6f (patch)
tree84a36dcaa37ad0b3d4e7bb32583fba080911a69e
parentfe448fa0fc6b02fd5c70da8f784476a9d27d70da (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/batch_comments/components/preview_dropdown.vue4
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue4
-rw-r--r--app/assets/javascripts/diffs/store/actions.js24
-rw-r--r--app/assets/javascripts/diffs/store/mutation_types.js3
-rw-r--r--app/assets/javascripts/diffs/store/mutations.js6
-rw-r--r--app/assets/javascripts/diffs/utils/file_reviews.js2
-rw-r--r--config/metrics/counts_28d/20211102205024_p_ci_templates_security_sast_iac_latest_monthly.yml26
-rw-r--r--config/metrics/counts_28d/20211102205223_p_ci_templates_implicit_security_sast_iac_latest_monthly.yml26
-rw-r--r--config/metrics/counts_28d/20211102213704_p_ci_templates_jobs_sast_iac_latest_monthly.yml26
-rw-r--r--config/metrics/counts_28d/20211102213921_p_ci_templates_implicit_jobs_sast_iac_latest_monthly.yml26
-rw-r--r--config/metrics/counts_7d/20211102202454_p_ci_templates_security_sast_iac_latest_weekly.yml27
-rw-r--r--config/metrics/counts_7d/20211102204352_p_ci_templates_implicit_security_sast_iac_latest_weekly.yml26
-rw-r--r--config/metrics/counts_7d/20211102213112_p_ci_templates_jobs_sast_iac_latest_weekly.yml26
-rw-r--r--config/metrics/counts_7d/20211102213417_p_ci_templates_implicit_jobs_sast_iac_latest_weekly.yml26
-rw-r--r--doc/architecture/blueprints/consolidating_groups_and_projects/index.md6
-rw-r--r--doc/ci/runners/build_cloud/linux_build_cloud.md2
-rw-r--r--doc/development/workspaces/index.md145
-rw-r--r--doc/user/workspace/index.md4
-rw-r--r--lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml34
-rw-r--r--lib/gitlab/ci/templates/Security/SAST-IaC.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/usage_data_counters/known_events/ci_templates.yml16
-rw-r--r--spec/frontend/batch_comments/components/preview_dropdown_spec.js6
-rw-r--r--spec/frontend/diffs/components/diff_file_header_spec.js13
-rw-r--r--spec/frontend/diffs/store/actions_spec.js47
-rw-r--r--spec/frontend/diffs/store/mutations_spec.js24
-rw-r--r--spec/frontend/diffs/utils/file_reviews_spec.js24
-rw-r--r--spec/lib/gitlab/ci/templates/Jobs/sast_iac_gitlab_ci_yaml_spec.rb65
27 files changed, 530 insertions, 110 deletions
diff --git a/app/assets/javascripts/batch_comments/components/preview_dropdown.vue b/app/assets/javascripts/batch_comments/components/preview_dropdown.vue
index 91b3b6a685c..e90c29e939f 100644
--- a/app/assets/javascripts/batch_comments/components/preview_dropdown.vue
+++ b/app/assets/javascripts/batch_comments/components/preview_dropdown.vue
@@ -15,14 +15,14 @@ export default {
...mapGetters('batchComments', ['draftsCount', 'sortedDrafts']),
},
methods: {
- ...mapActions('diffs', ['toggleActiveFileByHash']),
+ ...mapActions('diffs', ['setCurrentFileHash']),
...mapActions('batchComments', ['scrollToDraft']),
isLast(index) {
return index === this.sortedDrafts.length - 1;
},
async onClickDraft(draft) {
if (this.viewDiffsFileByFile && draft.file_hash) {
- await this.toggleActiveFileByHash(draft.file_hash);
+ await this.setCurrentFileHash(draft.file_hash);
}
await this.scrollToDraft(draft);
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 4bcb99424db..746646948fe 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -221,7 +221,7 @@ export default {
'toggleFileDiscussions',
'toggleFileDiscussionWrappers',
'toggleFullDiff',
- 'toggleActiveFileByHash',
+ 'setCurrentFileHash',
'reviewFile',
'setFileCollapsedByUser',
]),
@@ -244,7 +244,7 @@ export default {
scrollToElement(document.querySelector(selector));
window.location.hash = selector;
if (!this.viewDiffsFileByFile) {
- this.toggleActiveFileByHash(this.diffFile.file_hash);
+ this.setCurrentFileHash(this.diffFile.file_hash);
}
}
},
diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js
index 9e828450acf..692cb913a57 100644
--- a/app/assets/javascripts/diffs/store/actions.js
+++ b/app/assets/javascripts/diffs/store/actions.js
@@ -85,6 +85,12 @@ export const setBaseConfig = ({ commit }, options) => {
viewDiffsFileByFile,
mrReviews,
});
+
+ Array.from(new Set(Object.values(mrReviews).flat())).forEach((id) => {
+ const viewedId = id.replace(/^hash:/, '');
+
+ commit(types.SET_DIFF_FILE_VIEWED, { id: viewedId, seen: true });
+ });
};
export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
@@ -127,7 +133,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
}
if (!isNoteLink && !state.currentDiffFileId) {
- commit(types.VIEW_DIFF_FILE, diff_files[0]?.file_hash);
+ commit(types.SET_CURRENT_DIFF_FILE, diff_files[0]?.file_hash);
}
if (isNoteLink) {
@@ -143,7 +149,7 @@ export const fetchDiffFilesBatch = ({ commit, state, dispatch }) => {
!state.diffFiles.some((f) => f.file_hash === state.currentDiffFileId) &&
!isNoteLink
) {
- commit(types.VIEW_DIFF_FILE, state.diffFiles[0].file_hash);
+ commit(types.SET_CURRENT_DIFF_FILE, state.diffFiles[0].file_hash);
}
if (state.diffFiles?.length) {
@@ -248,7 +254,7 @@ export const fetchCoverageFiles = ({ commit, state }) => {
export const setHighlightedRow = ({ commit }, lineCode) => {
const fileHash = lineCode.split('_')[0];
commit(types.SET_HIGHLIGHTED_ROW, lineCode);
- commit(types.VIEW_DIFF_FILE, fileHash);
+ commit(types.SET_CURRENT_DIFF_FILE, fileHash);
handleLocationHash();
};
@@ -514,8 +520,8 @@ export const toggleTreeOpen = ({ commit }, path) => {
commit(types.TOGGLE_FOLDER_OPEN, path);
};
-export const toggleActiveFileByHash = ({ commit }, hash) => {
- commit(types.VIEW_DIFF_FILE, hash);
+export const setCurrentFileHash = ({ commit }, hash) => {
+ commit(types.SET_CURRENT_DIFF_FILE, hash);
};
export const scrollToFile = ({ state, commit, getters }, { path, setHash = true }) => {
@@ -523,7 +529,7 @@ export const scrollToFile = ({ state, commit, getters }, { path, setHash = true
const { fileHash } = state.treeEntries[path];
- commit(types.VIEW_DIFF_FILE, fileHash);
+ commit(types.SET_CURRENT_DIFF_FILE, fileHash);
if (getters.isVirtualScrollingEnabled) {
eventHub.$emit('scrollToFileHash', fileHash);
@@ -806,7 +812,7 @@ export const setCurrentDiffFileIdFromNote = ({ commit, state, rootGetters }, not
const fileHash = rootGetters.getDiscussion(note.discussion_id).diff_file?.file_hash;
if (fileHash && state.diffFiles.some((f) => f.file_hash === fileHash)) {
- commit(types.VIEW_DIFF_FILE, fileHash);
+ commit(types.SET_CURRENT_DIFF_FILE, fileHash);
}
};
@@ -814,7 +820,7 @@ export const navigateToDiffFileIndex = ({ commit, state }, index) => {
const fileHash = state.diffFiles[index].file_hash;
document.location.hash = fileHash;
- commit(types.VIEW_DIFF_FILE, fileHash);
+ commit(types.SET_CURRENT_DIFF_FILE, fileHash);
};
export const setFileByFile = ({ state, commit }, { fileByFile }) => {
@@ -850,6 +856,8 @@ export function reviewFile({ commit, state }, { file, reviewed = true }) {
const reviews = markFileReview(state.mrReviews, file, reviewed);
setReviewsForMergeRequest(mrPath, reviews);
+
+ commit(types.SET_DIFF_FILE_VIEWED, { id: file.file_hash, seen: reviewed });
commit(types.SET_MR_FILE_REVIEWS, reviews);
}
diff --git a/app/assets/javascripts/diffs/store/mutation_types.js b/app/assets/javascripts/diffs/store/mutation_types.js
index 60836f747f5..51c21c1bfc4 100644
--- a/app/assets/javascripts/diffs/store/mutation_types.js
+++ b/app/assets/javascripts/diffs/store/mutation_types.js
@@ -20,7 +20,8 @@ export const SET_LINE_DISCUSSIONS_FOR_FILE = 'SET_LINE_DISCUSSIONS_FOR_FILE';
export const REMOVE_LINE_DISCUSSIONS_FOR_FILE = 'REMOVE_LINE_DISCUSSIONS_FOR_FILE';
export const TOGGLE_FOLDER_OPEN = 'TOGGLE_FOLDER_OPEN';
export const SET_SHOW_TREE_LIST = 'SET_SHOW_TREE_LIST';
-export const VIEW_DIFF_FILE = 'VIEW_DIFF_FILE';
+export const SET_CURRENT_DIFF_FILE = 'SET_CURRENT_DIFF_FILE';
+export const SET_DIFF_FILE_VIEWED = 'SET_DIFF_FILE_VIEWED';
export const OPEN_DIFF_FILE_COMMENT_FORM = 'OPEN_DIFF_FILE_COMMENT_FORM';
export const UPDATE_DIFF_FILE_COMMENT_FORM = 'UPDATE_DIFF_FILE_COMMENT_FORM';
diff --git a/app/assets/javascripts/diffs/store/mutations.js b/app/assets/javascripts/diffs/store/mutations.js
index 6bc927b9d1f..4a9df0eafcc 100644
--- a/app/assets/javascripts/diffs/store/mutations.js
+++ b/app/assets/javascripts/diffs/store/mutations.js
@@ -254,9 +254,11 @@ export default {
[types.SET_SHOW_TREE_LIST](state, showTreeList) {
state.showTreeList = showTreeList;
},
- [types.VIEW_DIFF_FILE](state, fileId) {
+ [types.SET_CURRENT_DIFF_FILE](state, fileId) {
state.currentDiffFileId = fileId;
- Vue.set(state.viewedDiffFileIds, fileId, true);
+ },
+ [types.SET_DIFF_FILE_VIEWED](state, { id, seen }) {
+ Vue.set(state.viewedDiffFileIds, id, seen);
},
[types.OPEN_DIFF_FILE_COMMENT_FORM](state, formData) {
state.commentForms.push({
diff --git a/app/assets/javascripts/diffs/utils/file_reviews.js b/app/assets/javascripts/diffs/utils/file_reviews.js
index 7a4b1aa6b17..227be4e4a6c 100644
--- a/app/assets/javascripts/diffs/utils/file_reviews.js
+++ b/app/assets/javascripts/diffs/utils/file_reviews.js
@@ -52,8 +52,10 @@ export function markFileReview(reviews, file, reviewed = true) {
if (reviewed) {
fileReviews.add(file.id);
+ fileReviews.add(`hash:${file.file_hash}`);
} else {
fileReviews.delete(file.id);
+ fileReviews.delete(`hash:${file.file_hash}`);
}
updatedReviews[file.file_identifier_hash] = Array.from(fileReviews);
diff --git a/config/metrics/counts_28d/20211102205024_p_ci_templates_security_sast_iac_latest_monthly.yml b/config/metrics/counts_28d/20211102205024_p_ci_templates_security_sast_iac_latest_monthly.yml
new file mode 100644
index 00000000000..c9589f3ff29
--- /dev/null
+++ b/config/metrics/counts_28d/20211102205024_p_ci_templates_security_sast_iac_latest_monthly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_sast_iac_latest_monthly
+description: Count of pipelines using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73076
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_sast_iac_latest
diff --git a/config/metrics/counts_28d/20211102205223_p_ci_templates_implicit_security_sast_iac_latest_monthly.yml b/config/metrics/counts_28d/20211102205223_p_ci_templates_implicit_security_sast_iac_latest_monthly.yml
new file mode 100644
index 00000000000..9e5724b1e40
--- /dev/null
+++ b/config/metrics/counts_28d/20211102205223_p_ci_templates_implicit_security_sast_iac_latest_monthly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_sast_iac_latest_monthly
+description: Count of pipelines with implicit runs using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73076
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_sast_iac_latest
diff --git a/config/metrics/counts_28d/20211102213704_p_ci_templates_jobs_sast_iac_latest_monthly.yml b/config/metrics/counts_28d/20211102213704_p_ci_templates_jobs_sast_iac_latest_monthly.yml
new file mode 100644
index 00000000000..40aa9cdbab1
--- /dev/null
+++ b/config/metrics/counts_28d/20211102213704_p_ci_templates_jobs_sast_iac_latest_monthly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_sast_iac_latest_monthly
+description: Count of pipelines using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73074
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_sast_iac_latest
diff --git a/config/metrics/counts_28d/20211102213921_p_ci_templates_implicit_jobs_sast_iac_latest_monthly.yml b/config/metrics/counts_28d/20211102213921_p_ci_templates_implicit_jobs_sast_iac_latest_monthly.yml
new file mode 100644
index 00000000000..3fa3c751366
--- /dev/null
+++ b/config/metrics/counts_28d/20211102213921_p_ci_templates_implicit_jobs_sast_iac_latest_monthly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_sast_iac_latest_monthly
+description: Count of pipelines with implicit runs using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73074
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_sast_iac_latest
diff --git a/config/metrics/counts_7d/20211102202454_p_ci_templates_security_sast_iac_latest_weekly.yml b/config/metrics/counts_7d/20211102202454_p_ci_templates_security_sast_iac_latest_weekly.yml
new file mode 100644
index 00000000000..e7e2c096902
--- /dev/null
+++ b/config/metrics/counts_7d/20211102202454_p_ci_templates_security_sast_iac_latest_weekly.yml
@@ -0,0 +1,27 @@
+---
+data_category: optional
+key_path: redis_hll_counters.ci_templates.p_ci_templates_security_sast_iac_latest_weekly
+description: Count of pipelines using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73076
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_security_sast_iac_latest
diff --git a/config/metrics/counts_7d/20211102204352_p_ci_templates_implicit_security_sast_iac_latest_weekly.yml b/config/metrics/counts_7d/20211102204352_p_ci_templates_implicit_security_sast_iac_latest_weekly.yml
new file mode 100644
index 00000000000..09070adb2c1
--- /dev/null
+++ b/config/metrics/counts_7d/20211102204352_p_ci_templates_implicit_security_sast_iac_latest_weekly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_security_sast_iac_latest_weekly
+description: Count of pipelines with implicit runs using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73076
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_security_sast_iac_latest
diff --git a/config/metrics/counts_7d/20211102213112_p_ci_templates_jobs_sast_iac_latest_weekly.yml b/config/metrics/counts_7d/20211102213112_p_ci_templates_jobs_sast_iac_latest_weekly.yml
new file mode 100644
index 00000000000..3fdd37bffa5
--- /dev/null
+++ b/config/metrics/counts_7d/20211102213112_p_ci_templates_jobs_sast_iac_latest_weekly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_jobs_sast_iac_latest_weekly
+description: Count of pipelines using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73074
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_jobs_sast_iac_latest
diff --git a/config/metrics/counts_7d/20211102213417_p_ci_templates_implicit_jobs_sast_iac_latest_weekly.yml b/config/metrics/counts_7d/20211102213417_p_ci_templates_implicit_jobs_sast_iac_latest_weekly.yml
new file mode 100644
index 00000000000..3a58cd033f2
--- /dev/null
+++ b/config/metrics/counts_7d/20211102213417_p_ci_templates_implicit_jobs_sast_iac_latest_weekly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_templates.p_ci_templates_implicit_jobs_sast_iac_latest_weekly
+description: Count of pipelines with implicit runs using the latest SAST IaC template
+product_section: sec
+product_stage: secure
+product_group: "group::static analysis"
+product_category: SAST
+value_type: number
+status: active
+milestone: "14.5"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73074
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+options:
+ events:
+ - p_ci_templates_implicit_jobs_sast_iac_latest
diff --git a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
index d75c2c8e703..53357220755 100644
--- a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
+++ b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
@@ -139,7 +139,7 @@ The initial iteration will provide a framework to house features under `Namespac
1. **Tier**: Is there any tier functionality that is differentiated by projects and groups?
1. **Documentation**: Is the structure and content of documentation impacted by these changes at all?
1. **Solution proposal**:
- - Think big: This analysis provides a great opportunity to zoom out and consider the feature UX as a whole. How could you make this feature lovable based on the new structure, inheritance, and capabilities afforded by `Namespaces`? Is there any UI which doesn't comply with Pajamas?
+ - Think big: This analysis provides a great opportunity to zoom out and consider the feature UX as a whole. How could you make this feature lovable based on the new structure, inheritance, and capabilities afforded by `Namespaces`? Is there any UI which doesn't comply with Pajamas?
- Start small: What are the product changes that need to be made to assist with the migration?
- Move fast: Prioritise these solution ideas, document in issues, and create a roadmap for implementation.
@@ -170,3 +170,7 @@ DRIs:
| Design | Nick Post |
<!-- vale gitlab.Spelling = YES -->
+
+## Related topics
+
+- [Workspaces developer documentation](../../../development/workspaces/index.md)
diff --git a/doc/ci/runners/build_cloud/linux_build_cloud.md b/doc/ci/runners/build_cloud/linux_build_cloud.md
index 6cdc93591a7..ae9a4c4620d 100644
--- a/doc/ci/runners/build_cloud/linux_build_cloud.md
+++ b/doc/ci/runners/build_cloud/linux_build_cloud.md
@@ -31,6 +31,8 @@ Below are the runners' settings.
| Default Docker image | `ruby:2.5` | - |
| `privileged` (run [Docker in Docker](https://hub.docker.com/_/docker/)) | `true` | `false` |
+These runners share a [distributed cache](https://docs.gitlab.com/runner/configuration/autoscale.html#distributed-runners-caching) through use of a Google Cloud Storage (GCS) bucket. Cache contents not updated within the last 14 days are automatically removed through use of an [object lifecycle management policy](https://cloud.google.com/storage/docs/lifecycle).
+
## Pre-clone script
Build Cloud runners for Linux provide a way to run commands in a CI
diff --git a/doc/development/workspaces/index.md b/doc/development/workspaces/index.md
index 9fb5f404061..b36c79e84d7 100644
--- a/doc/development/workspaces/index.md
+++ b/doc/development/workspaces/index.md
@@ -9,87 +9,112 @@ description: "Development Guidelines: learn about workspaces when developing Git
# Workspaces
-[Read more](../../user/workspace/index.md) about the workspaces initiative.
+The [Workspaces initiative](../../user/workspace/index.md) focuses on reaching feature parity between
+SaaS and self-managed installations.
-## Consolidate Groups and Projects
+## Consolidate groups and projects
- [Architecture blueprint](../../architecture/blueprints/consolidating_groups_and_projects/index.md)
-Consolidate Groups and Projects is one facet of the workspaces initiative, addressing the feature disparity between
-groups and projects.
+One facet of the workspaces initiative is to consolidate groups and projects,
+addressing the feature disparity between them. Some features, such as epics, are
+only available at the group level. Some features, such as issues, are only available
+at the project level. Other features, such as milestones, are available to both groups
+and projects.
-There is feature disparity between groups and projects. Some features only available at group level (for example epics).
-Some features only available at project level (for example issues). And some features available at both levels
-(for example labels, milestones).
+We receive many requests to add features either to the group or project level.
+Moving features around to different levels is problematic on multiple levels:
-We get more and more requests to get one feature or another added to either group or project level. This takes
-engineering time, to just move features around to different levels. This also adds a UX overhead of keeping a mental
-model of which features are available at which level.
+- It requires engineering time to move the features.
+- It requires UX overhead to maintain mental models of feature availability.
+- It creates redundant code.
-This also creates lots of redundant code. Features get copied from project, to group to instance level with small
-nuances between them. This also causes extra maintenance, when something needs to be fixed. The fix is copied to
-several locations. This also creates different user experience for the same feature but in the different locations.
+When features are copied from one level (project, group, or instance) to another,
+the copies often have small, nuanced differences between them. These nuances cause
+extra engineering time when fixes are needed, because the fix must be copied to
+several locations. These nuances also create different user experiences when the
+feature is used in different places.
-To solve this we are moving towards consolidating groups and projects into a single entity, namespace. The work on this
-solution is split into several phases and is tracked in [epic 6473](https://gitlab.com/groups/gitlab-org/-/epics/6473).
+A solution for this problem is to consolidate groups and projects into a single
+entity, `namespace`. The work on this solution is split into several phases and
+is tracked in [epic 6473](https://gitlab.com/groups/gitlab-org/-/epics/6473).
### Phase 1
-Epic tracking [Phase 1](https://gitlab.com/groups/gitlab-org/-/epics/6697)
-
-Goal of Phase 1 is to ensure that every project gets a corresponding record in `namespaces` table with `type='Project'`.
-For user namespaces, type changes from `NULL` to `User`.
-
-Places where we should make sure project and project namespace go hand in hand:
-
-- Create project.
- - Use Rails callbacks to ensure a new project namespace is created for each project.
- - In this case project namespace records should have `created_at`/`updated_at` attributes equal to project's `created_at`/`updated_at` attributes.
-- Update Project.
- - Use Rails `after_save` callback to ensure some attributes are kept in sync between project and project namespaces,
- see [project#after_save](https://gitlab.com/gitlab-org/gitlab/blob/6d26634e864d7b748dda0e283eb2477362263bc3/app/models/project.rb#L101-L101).
-- Delete project.
- - Use FKs cascade delete or Rails callbacks to ensure when either a `Project` or its `ProjectNamespace` is removed its
- corresponding `ProjectNamespace` or `Project` respectively is removed as well.
-- Transfer project to a different group.
- - Make sure that when a project is transferred, its corresponding project namespace is transferred to the same group.
-- Transfer group.
- - Make sure when transferring a group that all of its sub projects, either direct or through descendant groups, have their
- corresponding project namespaces transferred correctly as well.
-- Export/import project.
- - Export project would continue to only export the project and not its project namespace in this phase. Project
- namespace does not contain any specific information that has to be exported at this point. Eventually we want the
- project namespace to be exported as well.
- - Import creates a new project, so project namespace is created through Rails `after_save` callback on the project model.
-- Export/import group.
- - As of this writing, when importing or exporting a `Group`, `Project`s are not included in the operation. If that functionality is changed to include `Project` when its Group is imported/exported, the logic must be sure to include their corresponding project namespaces in the import/export.
-
-After ensuring the above points, we plan to run a DB migration to create a `ProjectNamespace` record for every `Project`.
-Project namespace records created during migration should have `created_at`/`updated_at` attributes set to migration
-runtime. That means that project namespaces `created_at`/`updated_at` attributes don't match their corresponding
-project's `created_at`/`updated_at` attributes. We want the different dates to help audit any of the created project
-namespaces, in case we need it. We plan to run the back-filling migration in 14.5 milestone.
+- [Phase 1 epic](https://gitlab.com/groups/gitlab-org/-/epics/6697).
+- **Goals**:
+ 1. Ensure every project receives a corresponding record in the `namespaces`
+ table with `type='Project'`.
+ 1. For user namespaces, the type changes from `NULL` to `User`.
+
+We should make sure that projects, and the project namespace, are equivalent:
+
+- **Create project:** use Rails callbacks to ensure a new project namespace is
+ created for each project. Project namespace records should contain `created_at` and
+ `updated_at` attributes equal to the project's `created_at`/`updated_at` attributes.
+- **Update project:** use the `after_save` callback in Rails to ensure some
+ attributes are kept in sync between project and project namespaces.
+ Read [`project#after_save`](https://gitlab.com/gitlab-org/gitlab/blob/6d26634e864d7b748dda0e283eb2477362263bc3/app/models/project.rb#L101-L101)
+ for more information.
+- **Delete project:** use FKs cascade delete or Rails callbacks to ensure when a `Project`
+ or its `ProjectNamespace` is removed, its corresponding `ProjectNamespace` or `Project`
+ is also removed.
+- **Transfer project to a different group:** make sure that when a project is transferred,
+ its corresponding project namespace is transferred to the same group.
+- **Transfer group:** make sure when transferring a group that all of its sub-projects,
+ either direct or through descendant groups, have their corresponding project
+ namespaces transferred correctly as well.
+- **Export or import project**
+ - **Export project** continues to export only the project, and not its project namespace,
+ in this phase. The project namespace does not contain any specific information
+ to export at this point. Eventually we want the project namespace to be exported as well.
+ - **Import project** creates a new project, so the project namespace is created through
+ Rails `after_save` callback on the project model.
+- **Export or import group:** when importing or exporting a `Group`, projects are not
+ included in the operation. If that feature is changed to include `Project` when its group is
+ imported or exported, the logic must include their corresponding project namespaces
+ in the import or export.
+
+After ensuring these points, run a database migration to create a `ProjectNamespace`
+record for every `Project`. Project namespace records created during the migration
+should have `created_at` and `updated_at` attributes set to the migration runtime.
+The project namespaces' `created_at` and `updated_at` attributes would not match
+their corresponding project's `created_at` and `updated_at` attributes. We want
+the different dates to help audit any of the created project namespaces, in case we need it.
+After this work completes, we must migrate data as described in
+[Backfill `ProjectNamespace` for every Project](https://gitlab.com/gitlab-org/gitlab/-/issues/337100).
### Phase 2
-Epic tracking [Phase 2](https://gitlab.com/groups/gitlab-org/-/epics/6768)
+- [Phase 2 epic](https://gitlab.com/groups/gitlab-org/-/epics/6768).
+- **Goal**: Make `ProjectNamespace` the front entity to interact with instead of `Project`.
+
+In this phase:
+
+- Communicate the changes company-wide at the engineering level. We want to make
+ engineers aware of the upcoming changes, even though teams are not expected to
+ collaborate actively until phase 3.
+- Raise awareness to avoid regressions, and conflicting or duplicate work that
+ can be dealt with before phase 3.
-The focus of this phase is to make `ProjectNamespace` the front entity to interact with instead of `Project` .
Problems to solve as part of this phase:
-- Routes handling through project namespace rather than project.
+- Routes handling through `ProjectNamespace` rather than `Project`.
- Memberships handling.
- Policies handling.
-- Import/export.
+- Import and export.
- Other interactions between project namespace and project models.
-Communicate the changes company wide at the engineers level. We want engineers to be aware of the upcoming changes even
-though active collaboration of teams is expected only in phase 3. Raise awareness to avoid regressions, conflicting or duplicate work
-that can be taken care of even before phase 3.
-
### Phase 3
-Epic tracking [Phase 3](https://gitlab.com/groups/gitlab-org/-/epics/6585)
+- [Phase 3 epic](https://gitlab.com/groups/gitlab-org/-/epics/6585).
+- **Goal**: Feature parity between the namespace types.
+
+Phase 3 is when the active migration of features from `Project` to `ProjectNamespace`,
+or directly to `Namespace`, happens.
+
+## Related topics
-The focus of this phase is to get feature parity between the namespace types. Phase 3 is when active migration
-of features from `Project` to `ProjectNamespace` or directly to `Namespace` happens.
+- [Consolidating groups and projects](../../architecture/blueprints/consolidating_groups_and_projects/index.md)
+ architecture documentation
+- [Workspace user documentation](../../user/workspace/index.md)
diff --git a/doc/user/workspace/index.md b/doc/user/workspace/index.md
index d75d91f087d..8ca7f7defb2 100644
--- a/doc/user/workspace/index.md
+++ b/doc/user/workspace/index.md
@@ -46,3 +46,7 @@ The following provide a preview to the Workspace concept.
![Admin Overview](img/Admin_Settings.png)
![Admin Overview](img/hardware_settings.png)
+
+## Related topics
+
+- [Workspaces developer documentation](../../development/workspaces/index.md)
diff --git a/lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..b763705857e
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml
@@ -0,0 +1,34 @@
+variables:
+ # Setting this variable will affect all Security templates
+ # (SAST, Dependency Scanning, ...)
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
+
+iac-sast:
+ stage: test
+ artifacts:
+ reports:
+ sast: gl-sast-report.json
+ rules:
+ - when: never
+ # `rules` must be overridden explicitly by each child job
+ # see https://gitlab.com/gitlab-org/gitlab/-/issues/218444
+ variables:
+ SEARCH_MAX_DEPTH: 4
+ allow_failure: true
+ script:
+ - /analyzer run
+
+kics-iac-sast:
+ extends: iac-sast
+ image:
+ name: "$SAST_ANALYZER_IMAGE"
+ variables:
+ SAST_ANALYZER_IMAGE_TAG: 0
+ SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/kics:$SAST_ANALYZER_IMAGE_TAG"
+ rules:
+ - if: $SAST_DISABLED
+ when: never
+ - if: $SAST_EXCLUDED_ANALYZERS =~ /kics/
+ when: never
+ - if: $CI_COMMIT_BRANCH
diff --git a/lib/gitlab/ci/templates/Security/SAST-IaC.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST-IaC.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..8c0d72ff282
--- /dev/null
+++ b/lib/gitlab/ci/templates/Security/SAST-IaC.latest.gitlab-ci.yml
@@ -0,0 +1,2 @@
+include:
+ template: Jobs/SAST-IaC.latest.gitlab-ci.yml
diff --git a/lib/gitlab/usage_data_counters/known_events/ci_templates.yml b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
index 60a709e9a1d..40922433635 100644
--- a/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
+++ b/lib/gitlab/usage_data_counters/known_events/ci_templates.yml
@@ -83,6 +83,10 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
+- name: p_ci_templates_security_sast_iac_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_security_dast_runner_validation
category: ci_templates
redis_slot: ci_templates
@@ -267,6 +271,10 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
+- name: p_ci_templates_jobs_sast_iac_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_jobs_secret_detection
category: ci_templates
redis_slot: ci_templates
@@ -447,6 +455,10 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
+- name: p_ci_templates_implicit_jobs_sast_iac_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_implicit_jobs_secret_detection
category: ci_templates
redis_slot: ci_templates
@@ -503,6 +515,10 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
+- name: p_ci_templates_implicit_security_sast_iac_latest
+ category: ci_templates
+ redis_slot: ci_templates
+ aggregation: weekly
- name: p_ci_templates_implicit_security_dast_runner_validation
category: ci_templates
redis_slot: ci_templates
diff --git a/spec/frontend/batch_comments/components/preview_dropdown_spec.js b/spec/frontend/batch_comments/components/preview_dropdown_spec.js
index 41be04d0b7e..5327879f003 100644
--- a/spec/frontend/batch_comments/components/preview_dropdown_spec.js
+++ b/spec/frontend/batch_comments/components/preview_dropdown_spec.js
@@ -7,7 +7,7 @@ Vue.use(Vuex);
let wrapper;
-const toggleActiveFileByHash = jest.fn();
+const setCurrentFileHash = jest.fn();
const scrollToDraft = jest.fn();
function factory({ viewDiffsFileByFile = false, draftsCount = 1, sortedDrafts = [] } = {}) {
@@ -16,7 +16,7 @@ function factory({ viewDiffsFileByFile = false, draftsCount = 1, sortedDrafts =
diffs: {
namespaced: true,
actions: {
- toggleActiveFileByHash,
+ setCurrentFileHash,
},
state: {
viewDiffsFileByFile,
@@ -51,7 +51,7 @@ describe('Batch comments preview dropdown', () => {
await Vue.nextTick();
- expect(toggleActiveFileByHash).toHaveBeenCalledWith(expect.anything(), 'hash');
+ expect(setCurrentFileHash).toHaveBeenCalledWith(expect.anything(), 'hash');
expect(scrollToDraft).toHaveBeenCalledWith(expect.anything(), { id: 1, file_hash: 'hash' });
});
diff --git a/spec/frontend/diffs/components/diff_file_header_spec.js b/spec/frontend/diffs/components/diff_file_header_spec.js
index b16ef8fe6b0..e39b761b54d 100644
--- a/spec/frontend/diffs/components/diff_file_header_spec.js
+++ b/spec/frontend/diffs/components/diff_file_header_spec.js
@@ -7,7 +7,7 @@ import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import { DIFF_FILE_AUTOMATIC_COLLAPSE, DIFF_FILE_MANUAL_COLLAPSE } from '~/diffs/constants';
import { reviewFile } from '~/diffs/store/actions';
-import { SET_MR_FILE_REVIEWS } from '~/diffs/store/mutation_types';
+import { SET_DIFF_FILE_VIEWED, SET_MR_FILE_REVIEWS } from '~/diffs/store/mutation_types';
import { diffViewerModes } from '~/ide/constants';
import { scrollToElement } from '~/lib/utils/common_utils';
import { truncateSha } from '~/lib/utils/text_utility';
@@ -23,6 +23,7 @@ jest.mock('~/lib/utils/common_utils');
const diffFile = Object.freeze(
Object.assign(diffDiscussionsMockData.diff_file, {
id: '123',
+ file_hash: 'xyz',
file_identifier_hash: 'abc',
edit_path: 'link:/to/edit/path',
blob: {
@@ -58,7 +59,7 @@ describe('DiffFileHeader component', () => {
toggleFileDiscussions: jest.fn(),
toggleFileDiscussionWrappers: jest.fn(),
toggleFullDiff: jest.fn(),
- toggleActiveFileByHash: jest.fn(),
+ setCurrentFileHash: jest.fn(),
setFileCollapsedByUser: jest.fn(),
reviewFile: jest.fn(),
},
@@ -553,7 +554,13 @@ describe('DiffFileHeader component', () => {
reviewFile,
{ file, reviewed: true },
{},
- [{ type: SET_MR_FILE_REVIEWS, payload: { [file.file_identifier_hash]: [file.id] } }],
+ [
+ { type: SET_DIFF_FILE_VIEWED, payload: { id: file.file_hash, seen: true } },
+ {
+ type: SET_MR_FILE_REVIEWS,
+ payload: { [file.file_identifier_hash]: [file.id, `hash:${file.file_hash}`] },
+ },
+ ],
[],
);
});
diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 11ef3985abc..b5003a54917 100644
--- a/spec/frontend/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -99,6 +99,10 @@ describe('DiffsStoreActions', () => {
const projectPath = '/root/project';
const dismissEndpoint = '/-/user_callouts';
const showSuggestPopover = false;
+ const mrReviews = {
+ a: ['z', 'hash:a'],
+ b: ['y', 'hash:a'],
+ };
testAction(
setBaseConfig,
@@ -110,6 +114,7 @@ describe('DiffsStoreActions', () => {
projectPath,
dismissEndpoint,
showSuggestPopover,
+ mrReviews,
},
{
endpoint: '',
@@ -131,8 +136,21 @@ describe('DiffsStoreActions', () => {
projectPath,
dismissEndpoint,
showSuggestPopover,
+ mrReviews,
},
},
+ {
+ type: types.SET_DIFF_FILE_VIEWED,
+ payload: { id: 'z', seen: true },
+ },
+ {
+ type: types.SET_DIFF_FILE_VIEWED,
+ payload: { id: 'a', seen: true },
+ },
+ {
+ type: types.SET_DIFF_FILE_VIEWED,
+ payload: { id: 'y', seen: true },
+ },
],
[],
done,
@@ -190,10 +208,10 @@ describe('DiffsStoreActions', () => {
{ type: types.SET_RETRIEVING_BATCHES, payload: true },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res1.diff_files } },
{ type: types.SET_BATCH_LOADING_STATE, payload: 'loaded' },
- { type: types.VIEW_DIFF_FILE, payload: 'test' },
+ { type: types.SET_CURRENT_DIFF_FILE, payload: 'test' },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res2.diff_files } },
{ type: types.SET_BATCH_LOADING_STATE, payload: 'loaded' },
- { type: types.VIEW_DIFF_FILE, payload: 'test2' },
+ { type: types.SET_CURRENT_DIFF_FILE, payload: 'test2' },
{ type: types.SET_RETRIEVING_BATCHES, payload: false },
{ type: types.SET_BATCH_LOADING_STATE, payload: 'error' },
],
@@ -307,7 +325,7 @@ describe('DiffsStoreActions', () => {
it('should mark currently selected diff and set lineHash and fileHash of highlightedRow', () => {
testAction(setHighlightedRow, 'ABC_123', {}, [
{ type: types.SET_HIGHLIGHTED_ROW, payload: 'ABC_123' },
- { type: types.VIEW_DIFF_FILE, payload: 'ABC' },
+ { type: types.SET_CURRENT_DIFF_FILE, payload: 'ABC' },
]);
});
});
@@ -895,7 +913,7 @@ describe('DiffsStoreActions', () => {
expect(document.location.hash).toBe('#test');
});
- it('commits VIEW_DIFF_FILE', () => {
+ it('commits SET_CURRENT_DIFF_FILE', () => {
const state = {
treeEntries: {
path: {
@@ -906,7 +924,7 @@ describe('DiffsStoreActions', () => {
scrollToFile({ state, commit, getters }, { path: 'path' });
- expect(commit).toHaveBeenCalledWith(types.VIEW_DIFF_FILE, 'test');
+ expect(commit).toHaveBeenCalledWith(types.SET_CURRENT_DIFF_FILE, 'test');
});
});
@@ -1428,7 +1446,7 @@ describe('DiffsStoreActions', () => {
});
describe('setCurrentDiffFileIdFromNote', () => {
- it('commits VIEW_DIFF_FILE', () => {
+ it('commits SET_CURRENT_DIFF_FILE', () => {
const commit = jest.fn();
const state = { diffFiles: [{ file_hash: '123' }] };
const rootGetters = {
@@ -1438,10 +1456,10 @@ describe('DiffsStoreActions', () => {
setCurrentDiffFileIdFromNote({ commit, state, rootGetters }, '1');
- expect(commit).toHaveBeenCalledWith(types.VIEW_DIFF_FILE, '123');
+ expect(commit).toHaveBeenCalledWith(types.SET_CURRENT_DIFF_FILE, '123');
});
- it('does not commit VIEW_DIFF_FILE when discussion has no diff_file', () => {
+ it('does not commit SET_CURRENT_DIFF_FILE when discussion has no diff_file', () => {
const commit = jest.fn();
const state = { diffFiles: [{ file_hash: '123' }] };
const rootGetters = {
@@ -1454,7 +1472,7 @@ describe('DiffsStoreActions', () => {
expect(commit).not.toHaveBeenCalled();
});
- it('does not commit VIEW_DIFF_FILE when diff file does not exist', () => {
+ it('does not commit SET_CURRENT_DIFF_FILE when diff file does not exist', () => {
const commit = jest.fn();
const state = { diffFiles: [{ file_hash: '123' }] };
const rootGetters = {
@@ -1469,12 +1487,12 @@ describe('DiffsStoreActions', () => {
});
describe('navigateToDiffFileIndex', () => {
- it('commits VIEW_DIFF_FILE', (done) => {
+ it('commits SET_CURRENT_DIFF_FILE', (done) => {
testAction(
navigateToDiffFileIndex,
0,
{ diffFiles: [{ file_hash: '123' }] },
- [{ type: types.VIEW_DIFF_FILE, payload: '123' }],
+ [{ type: types.SET_CURRENT_DIFF_FILE, payload: '123' }],
[],
done,
);
@@ -1523,13 +1541,14 @@ describe('DiffsStoreActions', () => {
describe('reviewFile', () => {
const file = {
id: '123',
+ file_hash: 'xyz',
file_identifier_hash: 'abc',
load_collapsed_diff_url: 'gitlab-org/gitlab-test/-/merge_requests/1/diffs',
};
it.each`
- reviews | diffFile | reviewed
- ${{ abc: ['123'] }} | ${file} | ${true}
- ${{}} | ${file} | ${false}
+ reviews | diffFile | reviewed
+ ${{ abc: ['123', 'hash:xyz'] }} | ${file} | ${true}
+ ${{}} | ${file} | ${false}
`(
'sets reviews ($reviews) to localStorage and state for file $file if it is marked reviewed=$reviewed',
({ reviews, diffFile, reviewed }) => {
diff --git a/spec/frontend/diffs/store/mutations_spec.js b/spec/frontend/diffs/store/mutations_spec.js
index fc9ba223d5a..c104fcd5fb9 100644
--- a/spec/frontend/diffs/store/mutations_spec.js
+++ b/spec/frontend/diffs/store/mutations_spec.js
@@ -633,16 +633,36 @@ describe('DiffsStoreMutations', () => {
});
});
- describe('VIEW_DIFF_FILE', () => {
+ describe('SET_CURRENT_DIFF_FILE', () => {
it('updates currentDiffFileId', () => {
const state = createState();
- mutations[types.VIEW_DIFF_FILE](state, 'somefileid');
+ mutations[types.SET_CURRENT_DIFF_FILE](state, 'somefileid');
expect(state.currentDiffFileId).toBe('somefileid');
});
});
+ describe('SET_DIFF_FILE_VIEWED', () => {
+ let state;
+
+ beforeEach(() => {
+ state = {
+ viewedDiffFileIds: { 123: true },
+ };
+ });
+
+ it.each`
+ id | bool | outcome
+ ${'abc'} | ${true} | ${{ 123: true, abc: true }}
+ ${'123'} | ${false} | ${{ 123: false }}
+ `('sets the viewed files list to $bool for the id $id', ({ id, bool, outcome }) => {
+ mutations[types.SET_DIFF_FILE_VIEWED](state, { id, seen: bool });
+
+ expect(state.viewedDiffFileIds).toEqual(outcome);
+ });
+ });
+
describe('Set highlighted row', () => {
it('sets highlighted row', () => {
const state = createState();
diff --git a/spec/frontend/diffs/utils/file_reviews_spec.js b/spec/frontend/diffs/utils/file_reviews_spec.js
index 230ec12409c..ccd27a5ae3e 100644
--- a/spec/frontend/diffs/utils/file_reviews_spec.js
+++ b/spec/frontend/diffs/utils/file_reviews_spec.js
@@ -11,14 +11,14 @@ import {
function getDefaultReviews() {
return {
- abc: ['123', '098'],
+ abc: ['123', 'hash:xyz', '098', 'hash:uvw'],
};
}
describe('File Review(s) utilities', () => {
const mrPath = 'my/fake/mr/42';
const storageKey = `${mrPath}-file-reviews`;
- const file = { id: '123', file_identifier_hash: 'abc' };
+ const file = { id: '123', file_hash: 'xyz', file_identifier_hash: 'abc' };
const storedValue = JSON.stringify(getDefaultReviews());
let reviews;
@@ -44,14 +44,14 @@ describe('File Review(s) utilities', () => {
});
describe('reviewStatuses', () => {
- const file1 = { id: '123', file_identifier_hash: 'abc' };
- const file2 = { id: '098', file_identifier_hash: 'abc' };
+ const file1 = { id: '123', hash: 'xyz', file_identifier_hash: 'abc' };
+ const file2 = { id: '098', hash: 'uvw', file_identifier_hash: 'abc' };
it.each`
mrReviews | files | fileReviews
${{}} | ${[file1, file2]} | ${{ 123: false, '098': false }}
- ${{ abc: ['123'] }} | ${[file1, file2]} | ${{ 123: true, '098': false }}
- ${{ abc: ['098'] }} | ${[file1, file2]} | ${{ 123: false, '098': true }}
+ ${{ abc: ['123', 'hash:xyz'] }} | ${[file1, file2]} | ${{ 123: true, '098': false }}
+ ${{ abc: ['098', 'hash:uvw'] }} | ${[file1, file2]} | ${{ 123: false, '098': true }}
${{ def: ['123'] }} | ${[file1, file2]} | ${{ 123: false, '098': false }}
${{ abc: ['123'], def: ['098'] }} | ${[]} | ${{}}
`(
@@ -128,7 +128,7 @@ describe('File Review(s) utilities', () => {
describe('markFileReview', () => {
it("adds a review when there's nothing that already exists", () => {
- expect(markFileReview(null, file)).toStrictEqual({ abc: ['123'] });
+ expect(markFileReview(null, file)).toStrictEqual({ abc: ['123', 'hash:xyz'] });
});
it("overwrites an existing review if it's for the same file (identifier hash)", () => {
@@ -136,15 +136,15 @@ describe('File Review(s) utilities', () => {
});
it('removes a review from the list when `reviewed` is `false`', () => {
- expect(markFileReview(reviews, file, false)).toStrictEqual({ abc: ['098'] });
+ expect(markFileReview(reviews, file, false)).toStrictEqual({ abc: ['098', 'hash:uvw'] });
});
it('adds a new review if the file ID is new', () => {
- const updatedFile = { ...file, id: '098' };
- const allReviews = markFileReview({ abc: ['123'] }, updatedFile);
+ const updatedFile = { ...file, id: '098', file_hash: 'uvw' };
+ const allReviews = markFileReview({ abc: ['123', 'hash:xyz'] }, updatedFile);
expect(allReviews).toStrictEqual(getDefaultReviews());
- expect(allReviews.abc).toStrictEqual(['123', '098']);
+ expect(allReviews.abc).toStrictEqual(['123', 'hash:xyz', '098', 'hash:uvw']);
});
it.each`
@@ -158,7 +158,7 @@ describe('File Review(s) utilities', () => {
it('removes the file key if there are no more reviews for it', () => {
let updated = markFileReview(reviews, file, false);
- updated = markFileReview(updated, { ...file, id: '098' }, false);
+ updated = markFileReview(updated, { ...file, id: '098', file_hash: 'uvw' }, false);
expect(updated).toStrictEqual({});
});
diff --git a/spec/lib/gitlab/ci/templates/Jobs/sast_iac_gitlab_ci_yaml_spec.rb b/spec/lib/gitlab/ci/templates/Jobs/sast_iac_gitlab_ci_yaml_spec.rb
new file mode 100644
index 00000000000..b9256ece78b
--- /dev/null
+++ b/spec/lib/gitlab/ci/templates/Jobs/sast_iac_gitlab_ci_yaml_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Jobs/SAST-IaC.latest.gitlab-ci.yml' do
+ subject(:template) { Gitlab::Template::GitlabCiYmlTemplate.find('Jobs/SAST-IaC.latest') }
+
+ describe 'the created pipeline' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { project.owner }
+
+ let(:default_branch) { 'main' }
+ let(:pipeline_ref) { default_branch }
+ let(:service) { Ci::CreatePipelineService.new(project, user, ref: pipeline_ref) }
+ let(:pipeline) { service.execute!(:push).payload }
+ let(:build_names) { pipeline.builds.pluck(:name) }
+
+ before do
+ stub_ci_pipeline_yaml_file(template.content)
+ allow_next_instance_of(Ci::BuildScheduleWorker) do |instance|
+ allow(instance).to receive(:perform).and_return(true)
+ end
+ allow(project).to receive(:default_branch).and_return(default_branch)
+ end
+
+ context 'on feature branch' do
+ let(:pipeline_ref) { 'feature' }
+
+ it 'creates the kics-iac-sast job' do
+ expect(build_names).to contain_exactly('kics-iac-sast')
+ end
+ end
+
+ context 'on merge request' do
+ let(:service) { MergeRequests::CreatePipelineService.new(project: project, current_user: user) }
+ let(:merge_request) { create(:merge_request, :simple, source_project: project) }
+ let(:pipeline) { service.execute(merge_request).payload }
+
+ it 'has no jobs' do
+ expect(pipeline).to be_merge_request_event
+ expect(build_names).to be_empty
+ end
+ end
+
+ context 'SAST_DISABLED is set' do
+ before do
+ create(:ci_variable, key: 'SAST_DISABLED', value: 'true', project: project)
+ end
+
+ context 'on default branch' do
+ it 'has no jobs' do
+ expect { pipeline }.to raise_error(Ci::CreatePipelineService::CreateError)
+ end
+ end
+
+ context 'on feature branch' do
+ let(:pipeline_ref) { 'feature' }
+
+ it 'has no jobs' do
+ expect { pipeline }.to raise_error(Ci::CreatePipelineService::CreateError)
+ end
+ end
+ end
+ end
+end