From fab7ca985fc65409b3b1c312866f6faa302a77e6 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 23 Oct 2023 19:48:40 +1000 Subject: [PATCH 001/139] Trying to trigger MR in libs when on committing on main --- kibot-ci.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 5b3570b..d5da05a 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -105,6 +105,18 @@ image: git tag $CI_COMMIT_MESSAGE fi + merge_libs: + - | + if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then + for d in ["libs/melonlib", "libs/melon3d"] + do + cd $d + CURR_B=$(git rev-parse --abbrev-ref HEAD) + git push origin HEAD:$CURR_B -o merge_request.create -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + cd $CI_PROJECT_DIR + done + fi + output_mech: stage: gen_mech artifacts: @@ -152,6 +164,7 @@ outputs_all: - !reference [.commands, panel] - !reference [.commands, kibot] - !reference [.commands, neo] + - !reference [.commands, merge_libs] release_job: From 020d513b666538a4d2ec3d2be58fa9cad22f7fc4 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 08:59:12 +1000 Subject: [PATCH 002/139] Added to push so that the source branch isn't deleted for libs merge request --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index d5da05a..1751d21 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -112,7 +112,7 @@ image: do cd $d CURR_B=$(git rev-parse --abbrev-ref HEAD) - git push origin HEAD:$CURR_B -o merge_request.create -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + git push origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master cd $CI_PROJECT_DIR done fi From cf9aa5eb33d1e044ab2116eb14495b0a3a4c1b14 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 09:28:18 +1000 Subject: [PATCH 003/139] Added empty commit before creating MR in libs --- kibot-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 1751d21..5197504 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -112,6 +112,7 @@ image: do cd $d CURR_B=$(git rev-parse --abbrev-ref HEAD) + git commit --allow-empty -m "Merge" git push origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master cd $CI_PROJECT_DIR done From 1bfe4b81c31705e0c6359e4f334688c129f2bbbd Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 09:40:15 +1000 Subject: [PATCH 004/139] Updated post panel script to fix drc for mousebites --- .scripts/post_panel.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/.scripts/post_panel.py b/.scripts/post_panel.py index 99a13dc..c0806be 100644 --- a/.scripts/post_panel.py +++ b/.scripts/post_panel.py @@ -1,11 +1,38 @@ import json import sys +import shutil proj = sys.argv[1] +pcb = sys.argv[2] + +dest_folder = '/'.join(proj.split('/')[:-1]) +dest_name = proj.split('/')[-1].removesuffix(".kicad_pro") + +src_name = pcb.removesuffix(".kicad_pcb") +src_proj = src_name + ".kicad_pro" + +try: + shutil.copy(src_name + ".kicad_dru", dest_folder + "/" + dest_name + ".kicad_dru") +except Exception: + pass + +json_file = open(src_proj) +json_str = json_file.read() +src = json.loads(json_str) + json_file = open(proj) json_str = json_file.read() -d = json.loads(json_str) -d["board"]["design_settings"]["rule_severities"]["lib_footprint_issues"] = "ignore" -d["board"]["design_settings"]["rule_severities"]["lib_footprint_mismatch"] = "ignore" +dest = json.loads(json_str) +dest["board"]["design_settings"]["rule_severities"]["lib_footprint_issues"] = "ignore" +dest["board"]["design_settings"]["rule_severities"]["lib_footprint_mismatch"] = "ignore" +dest["board"]["design_settings"]["rule_severities"]["hole_near_hole"] = "ignore" +dest["board"]["design_settings"]["rule_severities"]["silk_overlap"] = "ignore" +dest["board"]["design_settings"]["rule_severities"]["silk_over_copper"] = "ignore" +# This one is just until kibot image is updated to 7.0.5 +dest["board"]["design_settings"]["rule_severities"]["copper_sliver"] = "ignore" +dest["net_settings"]["classes"] = src["net_settings"]["classes"] +dest["net_settings"]["netclass_patterns"] = src["net_settings"]["netclass_patterns"] + with open(proj, mode="w") as json_file: - json.dump(d, json_file, indent=2) + json.dump(dest, json_file, indent=2) + From 8f99c7529f3453ded828f22c1e47a5302ec3f7c9 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 10:01:00 +1000 Subject: [PATCH 005/139] Copy template sch file to panelized folder, instead of creating blank file --- kibot-ci.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 5197504..3415dc4 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -71,18 +71,19 @@ image: - 'SEARCH="_panel.json"' - !reference [.commands, get_dirs] - | + cd $CI_PROJECT_DIR for d in $DIRS do echo $d - cd $d - JSON=$(find *_panel.json) - NAME=$(echo "${JSON%.json}") - PCB=$(find *.kicad_pcb) - mkdir $CI_PROJECT_DIR/$NAME - kikit panelize -p $JSON $PCB $CI_PROJECT_DIR/$NAME/$NAME.kicad_pcb - touch $CI_PROJECT_DIR/$NAME/$NAME.kicad_sch - cp fp-lib-table $CI_PROJECT_DIR/$NAME/ - python3 $CI_PROJECT_DIR/.gitlab/.scripts/post_panel.py $CI_PROJECT_DIR/$NAME/$NAME.kicad_pro $PCB + JSON=$(find $d/*_panel.json) + FILE=$(basename "${JSON}") + NAME=$(echo "${FILE%.json}") + PCB=$(find $d/*.kicad_pcb) + mkdir $NAME + kikit panelize -p $JSON $PCB $NAME/$NAME.kicad_pcb + cp .gitlab/micromelon_default/micromelon_default.kicad_sch $NAME/$NAME.kicad_sch + cp $d/fp-lib-table $NAME/ + python3 .gitlab/.scripts/post_panel.py $NAME/$NAME.kicad_pro $PCB done - cd $CI_PROJECT_DIR From ae1ce7c19990b0e8c381d7dcbd4bee7a8cd37c45 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 10:23:10 +1000 Subject: [PATCH 006/139] Fixup base ci file. Fix bash loop in kibot-ci merge_libs --- base-gitlab.yaml | 4 +++- kibot-ci.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/base-gitlab.yaml b/base-gitlab.yaml index fb7c9d7..864e2c9 100644 --- a/base-gitlab.yaml +++ b/base-gitlab.yaml @@ -1 +1,3 @@ -include ".gitlab/kibot-ci.yaml" +include: + - project: 'Micromelon/education/hardware/kicad-ci' + file: '/kibot-ci.yml' diff --git a/kibot-ci.yml b/kibot-ci.yml index 3415dc4..06d8379 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -109,7 +109,7 @@ image: merge_libs: - | if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then - for d in ["libs/melonlib", "libs/melon3d"] + for d in "libs/melonlib" "libs/melon3d" do cd $d CURR_B=$(git rev-parse --abbrev-ref HEAD) From dff93b20ec61a13d10770c4c136bf7d1951c2ce3 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 10:41:02 +1000 Subject: [PATCH 007/139] Added git config before trying to push libs --- kibot-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 06d8379..aeb5287 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -109,6 +109,8 @@ image: merge_libs: - | if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then + git config --global user.name "KicadCi" + git config --global user.email "andrew@micromelon.com.au" for d in "libs/melonlib" "libs/melon3d" do cd $d From de6695158feb0d4a0b71d6df63c6cc419e18cac7 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 11:33:37 +1000 Subject: [PATCH 008/139] Fixing up pushing to libs on release by using auth token --- kibot-ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index aeb5287..c6f7db1 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -114,9 +114,13 @@ image: for d in "libs/melonlib" "libs/melon3d" do cd $d - CURR_B=$(git rev-parse --abbrev-ref HEAD) + SHA=$(git rev-parse HEAD) + CURR_B=$(git name-rev --name-only $SHA) + REPO=$(basename $(git remote get-url origin)) + git remote add gl_origin https://oauth2:$PRJ_AUTH_TOKEN@gitlab.com/Micromelon/eduation/hardware/$REPO + git checkout $CURR_B git commit --allow-empty -m "Merge" - git push origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + git push gl_origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master cd $CI_PROJECT_DIR done fi From be5d0410cfc7b2f6d3c5390e78669bb5ee397a52 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 13:01:24 +1000 Subject: [PATCH 009/139] Add individual project tokens for each of the libs. --- kibot-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index c6f7db1..346eb6e 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -114,10 +114,16 @@ image: for d in "libs/melonlib" "libs/melon3d" do cd $d + if [ $d == "libs/melonlib" ] + then + TOKEN=$KI_LIB_TOKEN + else + TOKEN=$KI_LIB_3D_TOKEN + fi SHA=$(git rev-parse HEAD) CURR_B=$(git name-rev --name-only $SHA) REPO=$(basename $(git remote get-url origin)) - git remote add gl_origin https://oauth2:$PRJ_AUTH_TOKEN@gitlab.com/Micromelon/eduation/hardware/$REPO + git remote add gl_origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git checkout $CURR_B git commit --allow-empty -m "Merge" git push gl_origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master From b8ea21802451230752a1eab277e8779535e592dc Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 13:12:00 +1000 Subject: [PATCH 010/139] printing to debug libs push --- kibot-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 346eb6e..0f9098f 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -126,6 +126,8 @@ image: git remote add gl_origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git checkout $CURR_B git commit --allow-empty -m "Merge" + echo $CURR_B + git remote get-url gl_origin git push gl_origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master cd $CI_PROJECT_DIR done From f09785a98fcc04196f1ab5ec44fe62ddf0a63431 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 13:35:45 +1000 Subject: [PATCH 011/139] Fetch before getting branches --- kibot-ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 0f9098f..60e2aea 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -111,6 +111,7 @@ image: if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then git config --global user.name "KicadCi" git config --global user.email "andrew@micromelon.com.au" + cd $CI_PROJECT_DIR for d in "libs/melonlib" "libs/melon3d" do cd $d @@ -120,13 +121,13 @@ image: else TOKEN=$KI_LIB_3D_TOKEN fi - SHA=$(git rev-parse HEAD) - CURR_B=$(git name-rev --name-only $SHA) + git fetch --all + CURR_B=$(git name-rev --name-only $(git rev-parse HEAD)) REPO=$(basename $(git remote get-url origin)) - git remote add gl_origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO - git checkout $CURR_B - git commit --allow-empty -m "Merge" echo $CURR_B + git checkout $CURR_B + git remote add gl_origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO + git commit --allow-empty -m "Merge" git remote get-url gl_origin git push gl_origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master cd $CI_PROJECT_DIR From 2747320f39d65b06444cb9c2f30f3a794710bb0b Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 13:43:52 +1000 Subject: [PATCH 012/139] Set remote url early for libs push --- kibot-ci.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 60e2aea..1e3f684 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -121,15 +121,14 @@ image: else TOKEN=$KI_LIB_3D_TOKEN fi + REPO=$(basename $(git remote get-url origin)) + git remote set-url origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git fetch --all CURR_B=$(git name-rev --name-only $(git rev-parse HEAD)) - REPO=$(basename $(git remote get-url origin)) echo $CURR_B git checkout $CURR_B - git remote add gl_origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git commit --allow-empty -m "Merge" - git remote get-url gl_origin - git push gl_origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + git push HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master cd $CI_PROJECT_DIR done fi From 1c2d4d73a0ca05ce895be842a9bcc966030dbe64 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 13:51:47 +1000 Subject: [PATCH 013/139] More debugging libs push --- kibot-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 1e3f684..f52124a 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -125,6 +125,9 @@ image: git remote set-url origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git fetch --all CURR_B=$(git name-rev --name-only $(git rev-parse HEAD)) + git rev-parse HEAD + git branch + git remote get-url origin echo $CURR_B git checkout $CURR_B git commit --allow-empty -m "Merge" From 21db6309381e9cd0e3f49bde776d1f08ac33b2c2 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 14:12:29 +1000 Subject: [PATCH 014/139] Trying different method of getting branch for libs push --- kibot-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index f52124a..3cce3d3 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -124,12 +124,12 @@ image: REPO=$(basename $(git remote get-url origin)) git remote set-url origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git fetch --all - CURR_B=$(git name-rev --name-only $(git rev-parse HEAD)) + CURR_B=$(git branch --remote --verbose --no-abbrev --contains | sed -rne 's/^[^\/]*\/([^\ ]+).*$/\1/p') git rev-parse HEAD git branch git remote get-url origin echo $CURR_B - git checkout $CURR_B + git checkout origin/$CURR_B git commit --allow-empty -m "Merge" git push HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master cd $CI_PROJECT_DIR From 98199c71d18eff216df04e79bdc8910ae5d49295 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 14:20:30 +1000 Subject: [PATCH 015/139] More debug push libs --- kibot-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 3cce3d3..348fd38 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -125,6 +125,7 @@ image: git remote set-url origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git fetch --all CURR_B=$(git branch --remote --verbose --no-abbrev --contains | sed -rne 's/^[^\/]*\/([^\ ]+).*$/\1/p') + git log git rev-parse HEAD git branch git remote get-url origin From b62264326ff06e36618828524860210e1af18a0b Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 14:28:56 +1000 Subject: [PATCH 016/139] Push libs debug --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 348fd38..8e7b604 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -127,7 +127,7 @@ image: CURR_B=$(git branch --remote --verbose --no-abbrev --contains | sed -rne 's/^[^\/]*\/([^\ ]+).*$/\1/p') git log git rev-parse HEAD - git branch + git branch --remote git remote get-url origin echo $CURR_B git checkout origin/$CURR_B From fdeaf321e0176b747dec49bf618eaff7ca9d840a Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 14:37:22 +1000 Subject: [PATCH 017/139] More push debugging --- kibot-ci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 8e7b604..a18d1d4 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -123,11 +123,10 @@ image: fi REPO=$(basename $(git remote get-url origin)) git remote set-url origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO - git fetch --all + git fetch origin CURR_B=$(git branch --remote --verbose --no-abbrev --contains | sed -rne 's/^[^\/]*\/([^\ ]+).*$/\1/p') - git log git rev-parse HEAD - git branch --remote + git branch -a git remote get-url origin echo $CURR_B git checkout origin/$CURR_B From fa65d5e060d76b3d8f204d4c61f4b02002592a21 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 14:46:00 +1000 Subject: [PATCH 018/139] Added --remote to submodule update flags, so that the branch is checked out --- kibot-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index a18d1d4..f2e6bb3 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -10,6 +10,7 @@ variables: GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_DEPTH: 1 GIT_SUBMODULE_FORCE_HTTPS: "true" + GIT_SUBMODULE_UPDATE_FLAGS: --remote stages: - gen_mech From 5a3315370b2c25b7639f7907856728ca97ca795a Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:00:23 +1000 Subject: [PATCH 019/139] Increase submodule depth to normal --- kibot-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index f2e6bb3..2913106 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -8,7 +8,6 @@ workflow: variables: GIT_STRATEGY: clone GIT_SUBMODULE_STRATEGY: recursive - GIT_SUBMODULE_DEPTH: 1 GIT_SUBMODULE_FORCE_HTTPS: "true" GIT_SUBMODULE_UPDATE_FLAGS: --remote From c08e147199b8b393a0883ca6cd4961f1c5c9841d Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:12:40 +1000 Subject: [PATCH 020/139] Non recursive submodules, and --merge flag for submodule update --- kibot-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 2913106..f03a474 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -7,9 +7,9 @@ workflow: variables: GIT_STRATEGY: clone - GIT_SUBMODULE_STRATEGY: recursive + GIT_SUBMODULE_STRATEGY: normal GIT_SUBMODULE_FORCE_HTTPS: "true" - GIT_SUBMODULE_UPDATE_FLAGS: --remote + GIT_SUBMODULE_UPDATE_FLAGS: --remote --merge stages: - gen_mech From 3d2d06f5b132972b407e107ffea4001c434d1cf5 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:22:30 +1000 Subject: [PATCH 021/139] Trying different submodule strategy --- kibot-ci.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index f03a474..254c06b 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -7,15 +7,21 @@ workflow: variables: GIT_STRATEGY: clone - GIT_SUBMODULE_STRATEGY: normal + # GIT_SUBMODULE_STRATEGY: normal GIT_SUBMODULE_FORCE_HTTPS: "true" - GIT_SUBMODULE_UPDATE_FLAGS: --remote --merge + # GIT_SUBMODULE_UPDATE_FLAGS: --remote --merge stages: - gen_mech - gen_fab - release +default: + before_script: + - git submodule update --init --remote --merge + - git submodule status + - git submodule foreach git log -1 + image: name: ghcr.io/inti-cmnb/kicad7_auto:1.6.3 From d6e8e0d96f7beaac5ae379294dc70c81a544c654 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:24:59 +1000 Subject: [PATCH 022/139] submodule strat normal --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 254c06b..ff81d0a 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -7,7 +7,7 @@ workflow: variables: GIT_STRATEGY: clone - # GIT_SUBMODULE_STRATEGY: normal + GIT_SUBMODULE_STRATEGY: normal GIT_SUBMODULE_FORCE_HTTPS: "true" # GIT_SUBMODULE_UPDATE_FLAGS: --remote --merge From e5358000efd9818411056237685ff60f1e51d29d Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:33:39 +1000 Subject: [PATCH 023/139] Trying changing submodule url in push libs job, before updating with remote --- kibot-ci.yml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index ff81d0a..691b1f7 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -16,12 +16,6 @@ stages: - gen_fab - release -default: - before_script: - - git submodule update --init --remote --merge - - git submodule status - - git submodule foreach git log -1 - image: name: ghcr.io/inti-cmnb/kicad7_auto:1.6.3 @@ -117,7 +111,6 @@ image: if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then git config --global user.name "KicadCi" git config --global user.email "andrew@micromelon.com.au" - cd $CI_PROJECT_DIR for d in "libs/melonlib" "libs/melon3d" do cd $d @@ -128,8 +121,16 @@ image: TOKEN=$KI_LIB_3D_TOKEN fi REPO=$(basename $(git remote get-url origin)) - git remote set-url origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO - git fetch origin + cd $CI_PROJECT_DIR + git submodule set-url $d https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO + done + git submodule update --init --remote --merge + git submodule status + git submodule foreach git log -1 + cd $CI_PROJECT_DIR + for d in "libs/melonlib" "libs/melon3d" + do + cd $d CURR_B=$(git branch --remote --verbose --no-abbrev --contains | sed -rne 's/^[^\/]*\/([^\ ]+).*$/\1/p') git rev-parse HEAD git branch -a From afc1a4faab457171fb5ea2b196563bbd7cf28207 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:40:27 +1000 Subject: [PATCH 024/139] Only update libs submodules in push job --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 691b1f7..813ad55 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -123,8 +123,8 @@ image: REPO=$(basename $(git remote get-url origin)) cd $CI_PROJECT_DIR git submodule set-url $d https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO + git submodule update --init --remote --merge $d done - git submodule update --init --remote --merge git submodule status git submodule foreach git log -1 cd $CI_PROJECT_DIR From 3ae5e59e96a2d0bdd1dc1f80f7051c04a8357ffe Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:48:52 +1000 Subject: [PATCH 025/139] Sync submodule before update --- kibot-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 813ad55..c48fdda 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -123,6 +123,7 @@ image: REPO=$(basename $(git remote get-url origin)) cd $CI_PROJECT_DIR git submodule set-url $d https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO + git submodule sync $d git submodule update --init --remote --merge $d done git submodule status From ecb24b8670f094ba36a1166d1fb09ac310f8e254 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 15:54:41 +1000 Subject: [PATCH 026/139] Try git pull in submodule --- kibot-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index c48fdda..1b0cad0 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -123,7 +123,10 @@ image: REPO=$(basename $(git remote get-url origin)) cd $CI_PROJECT_DIR git submodule set-url $d https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO - git submodule sync $d + cd $d + git fetch --all + git pull + cd $CI_PROJECT_DIR git submodule update --init --remote --merge $d done git submodule status From c3ce7bc471e422a2edbd0bd63be134a74e0394a1 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 16:01:41 +1000 Subject: [PATCH 027/139] Delete submodules from .git and the actual folder before updating --- kibot-ci.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 1b0cad0..8221cbb 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -111,6 +111,7 @@ image: if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then git config --global user.name "KicadCi" git config --global user.email "andrew@micromelon.com.au" + rm -rf .git/modules/libs for d in "libs/melonlib" "libs/melon3d" do cd $d @@ -122,11 +123,8 @@ image: fi REPO=$(basename $(git remote get-url origin)) cd $CI_PROJECT_DIR + rm -rf $d git submodule set-url $d https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO - cd $d - git fetch --all - git pull - cd $CI_PROJECT_DIR git submodule update --init --remote --merge $d done git submodule status From 7f6abf9dca7402b49149b20cb55f50965dd8a5f1 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 16:08:53 +1000 Subject: [PATCH 028/139] debugging submodule stuff --- kibot-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 8221cbb..c3668b2 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -111,6 +111,9 @@ image: if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then git config --global user.name "KicadCi" git config --global user.email "andrew@micromelon.com.au" + cd $CI_PROJECT_DIR + la + la .git rm -rf .git/modules/libs for d in "libs/melonlib" "libs/melon3d" do From bfa8f6e526dab37e28a9349da13ed3bcb6e799f5 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 16:12:48 +1000 Subject: [PATCH 029/139] No la alias --- kibot-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index c3668b2..2d7f096 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -112,8 +112,8 @@ image: git config --global user.name "KicadCi" git config --global user.email "andrew@micromelon.com.au" cd $CI_PROJECT_DIR - la - la .git + ls -a + ls -a .git rm -rf .git/modules/libs for d in "libs/melonlib" "libs/melon3d" do From 107f2d7443378d70367ea6200d7a6cb42e535805 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 16:21:11 +1000 Subject: [PATCH 030/139] Remove .git/modules folders after getting repo name --- kibot-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 2d7f096..78e9738 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -112,9 +112,6 @@ image: git config --global user.name "KicadCi" git config --global user.email "andrew@micromelon.com.au" cd $CI_PROJECT_DIR - ls -a - ls -a .git - rm -rf .git/modules/libs for d in "libs/melonlib" "libs/melon3d" do cd $d @@ -127,6 +124,7 @@ image: REPO=$(basename $(git remote get-url origin)) cd $CI_PROJECT_DIR rm -rf $d + rm -rf .git/modules/$d git submodule set-url $d https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git submodule update --init --remote --merge $d done From dfac3a068cc6561ffda65af3e316c13649e059df Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 16:52:42 +1000 Subject: [PATCH 031/139] Put check in place to not MR lib branch in sync with master. Get branch of libs submodules from .gitmodules --- kibot-ci.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 78e9738..567e1dd 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -129,19 +129,17 @@ image: git submodule update --init --remote --merge $d done git submodule status - git submodule foreach git log -1 cd $CI_PROJECT_DIR for d in "libs/melonlib" "libs/melon3d" do cd $d - CURR_B=$(git branch --remote --verbose --no-abbrev --contains | sed -rne 's/^[^\/]*\/([^\ ]+).*$/\1/p') - git rev-parse HEAD - git branch -a - git remote get-url origin - echo $CURR_B - git checkout origin/$CURR_B - git commit --allow-empty -m "Merge" - git push HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + if [ $(git rev-parse HEAD) != $(git rev-parse master) ] + then + CURR_B=$(git config -f $CI_PROJECT_DIR.gitmodules submodule.$d.branch) + git checkout $CURR_B + git commit --allow-empty -m "Merge" + git push HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + fi cd $CI_PROJECT_DIR done fi From e2955f66025ea8d59ea8b076e41245d0a9e0738e Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 17:00:48 +1000 Subject: [PATCH 032/139] Missed a slash in finding submodule branch command --- kibot-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 567e1dd..beb3952 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -135,9 +135,13 @@ image: cd $d if [ $(git rev-parse HEAD) != $(git rev-parse master) ] then - CURR_B=$(git config -f $CI_PROJECT_DIR.gitmodules submodule.$d.branch) + CURR_B=$(git config -f $CI_PROJECT_DIR/.gitmodules submodule.$d.branch) + echo CURR_B + echo $CURR_B git checkout $CURR_B + echo "about to commit" git commit --allow-empty -m "Merge" + echo "about to push" git push HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master fi cd $CI_PROJECT_DIR From b7d1c1c5b3af3bbcca6fad82be33c4fc501bb6d1 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 17:06:52 +1000 Subject: [PATCH 033/139] Try setting submodule origin manually --- kibot-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index beb3952..a3e68c0 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -127,9 +127,11 @@ image: rm -rf .git/modules/$d git submodule set-url $d https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO git submodule update --init --remote --merge $d + cd $d + git remote set-url origin https://ci_push:$TOKEN@gitlab.com/Micromelon/education/hardware/$REPO + cd $CI_PROJECT_DIR done git submodule status - cd $CI_PROJECT_DIR for d in "libs/melonlib" "libs/melon3d" do cd $d From 6c01737809c4e1fbe4b933b6d737c9ba946b7704 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 17:11:53 +1000 Subject: [PATCH 034/139] print get-url when about to push --- kibot-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index a3e68c0..f7ae816 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -144,7 +144,8 @@ image: echo "about to commit" git commit --allow-empty -m "Merge" echo "about to push" - git push HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + git remote get-url origin + git push -u origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master fi cd $CI_PROJECT_DIR done From 1df56d6acd3278b27a3ab670603e33d8e61c3c51 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 17:35:26 +1000 Subject: [PATCH 035/139] Switched to main instead of master for libs push --- kibot-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index f7ae816..bfde858 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -135,7 +135,7 @@ image: for d in "libs/melonlib" "libs/melon3d" do cd $d - if [ $(git rev-parse HEAD) != $(git rev-parse master) ] + if [ $(git rev-parse HEAD) != $(git rev-parse main) ] then CURR_B=$(git config -f $CI_PROJECT_DIR/.gitmodules submodule.$d.branch) echo CURR_B @@ -145,7 +145,7 @@ image: git commit --allow-empty -m "Merge" echo "about to push" git remote get-url origin - git push -u origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=master + git push -u origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=main fi cd $CI_PROJECT_DIR done From 9731f35f57476b3953f4c4bc37f77b0a53d5e0f5 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 17:48:02 +1000 Subject: [PATCH 036/139] Run git tag in dev --- kibot-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index bfde858..7260573 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -103,6 +103,7 @@ image: git_tag: - | if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then + echo "running git tag" git tag $CI_COMMIT_MESSAGE fi @@ -178,6 +179,7 @@ outputs_dev: SUFF_SCH: run_drc print_sch SUFF_PCB: run_erc,update_xml,set_text_variables print_pcb script: + - !reference [.commands, git_tag] - SUFFIX=$SUFF_SCH - !reference [.commands, kibot] - SUFFIX=$SUFF_PCB From 7f56cf75edbbbd7db985c5f67c641bdd1832d2d7 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 24 Oct 2023 18:12:08 +1000 Subject: [PATCH 037/139] Updated lib push flags to skip CI pipeline --- kibot-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 7260573..e7699f9 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -142,11 +142,9 @@ image: echo CURR_B echo $CURR_B git checkout $CURR_B - echo "about to commit" git commit --allow-empty -m "Merge" - echo "about to push" git remote get-url origin - git push -u origin HEAD:$CURR_B -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=main + git push -u origin HEAD:$CURR_B -o ci.skip -o merge_request.create -o merge_request.remove_source_branch=false -o merge_request.merge_when_pipeline_succeeds -o merge_request.target=main fi cd $CI_PROJECT_DIR done From d2427f29261b82ac2082e0a5850d0f116ca4531f Mon Sep 17 00:00:00 2001 From: ac Date: Fri, 27 Oct 2023 08:35:55 +1000 Subject: [PATCH 038/139] Cut 'rxx' from the end of revision tags --- default.kibot.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 29365c3..1359f84 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -11,7 +11,7 @@ preflight: run_drc: true set_text_variables: - name: 'rev' - command: "if [ $(git describe --tags | wc -w) -gt 0 ]; then git describe --tags; else echo $CI_COMMIT_SHORT_SHA; fi" + command: "if [ $(git describe --tags | wc -w) -gt 0 ]; then git describe --tags | sed -e 's/\([r,R][0-9]\+\)*$//g'; else echo $CI_COMMIT_SHORT_SHA; fi" - name: 'date' expand_kibot_patterns: true text: '%D' From 1a2043dceafa8758a4268d965e6ce5f3c7caf1ed Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 27 Oct 2023 09:23:38 +1000 Subject: [PATCH 039/139] Check mr title for invalid characters --- kibot-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index e7699f9..67c5819 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -102,9 +102,11 @@ image: git_tag: - | - if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then + if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then echo "running git tag" git tag $CI_COMMIT_MESSAGE + elif [[ $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" && "$CI_MERGE_REQUEST_TITLE" =~ [^a-zA-Z0-9.-_] ]]; then + exit 1 fi merge_libs: From d5eaab8bbbeaa0e81119b3d27daeb9c2fbc21547 Mon Sep 17 00:00:00 2001 From: ac Date: Mon, 30 Oct 2023 08:27:14 +1000 Subject: [PATCH 040/139] Created upload stage and job to run before release and upload to package registry Release job now links to the package registry --- kibot-ci.yml | 58 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 67c5819..c649190 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -10,10 +10,12 @@ variables: GIT_SUBMODULE_STRATEGY: normal GIT_SUBMODULE_FORCE_HTTPS: "true" # GIT_SUBMODULE_UPDATE_FLAGS: --remote --merge + PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/kicad/" stages: - gen_mech - gen_fab + - upload - release image: @@ -202,10 +204,9 @@ outputs_all: - !reference [.commands, neo] - !reference [.commands, merge_libs] - -release_job: - stage: release - image: registry.gitlab.com/gitlab-org/release-cli:latest +upload_job: + stage: upload + image: curlimages/curl:latest needs: - job: outputs_all artifacts: true @@ -213,19 +214,48 @@ release_job: - if: $CI_COMMIT_TAG when: never # Do not run this job when a tag is created manually - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + variables: + FAB_COMM: "curl --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" --upload-file Fabrication/$d ${PACKAGE_REGISTRY_URL}/$d" script: - - echo "running release_job for $TAG" + - | + for f in $(find Fabrication/ \! -type d) + do + curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $f ${PACKAGE_REGISTRY_URL}/$(filename $f) + done + artifacts: + when: always + paths: + - Fabrication/**/* + expire_in: 1 week + + +release_job: + stage: release + image: registry.gitlab.com/gitlab-org/release-cli:latest + needs: + - job: upload_job + artifacts: true + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + variables: + FAB_COMM: "echo \"--assets-link \"{\"name\":\"$d\",\"url\":\"${PACKAGE_REGISTRY_URL}/$CI_COMMIT_MESSAGE/$d\"}\" \\\"" + script: + - | + echo "running release_job for $CI_COMMIT_MESSAGE" + echo "#!/bin/bash" >> fab.sh + echo "release-cli create --name \"Release $CI_COMMIT_MESSAGE\" --tag-name $CI_COMMIT_MESSAGE \\" >> fab.sh + echo "--assets-link \"{\"name\":\"All\",\"url\":\"${PACKAGE_REGISTRY_URL}/$CI_COMMIT_MESSAGE\"}\" \\" >> fab.sh + for d in $(ls -d */) + do + echo "--assets-link \"{\"name\":\"$d\",\"url\":\"${PACKAGE_REGISTRY_URL}/$CI_COMMIT_MESSAGE/$d\"}\" \\" >> fab.sh + done + chmod u+x fab.sh + ./fab.sh artifacts: when: always name: "$CI_PROJECT_TITLE-$CI_COMMIT_MESSAGE" paths: - Fabrication/**/* - expire_in: never - release: # See https://docs.gitlab.com/ee/ci/yaml/#release for available properties - tag_name: '$CI_COMMIT_MESSAGE' # The version is incremented per pipeline. - description: '$CI_COMMIT_MESSAGE' - ref: '$CI_COMMIT_SHA' # The tag is created from the pipeline SHA. - assets: - links: - - name: All Fab - url: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/download" + expire_in: 1 week From a810b5af6168fdbcfe7b6712f5a473573ffc9771 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 3 Nov 2023 18:02:54 +1000 Subject: [PATCH 041/139] Changed quotes around rev env variable in deafult.kibot --- default.kibot.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 1359f84..98ed39c 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -11,7 +11,7 @@ preflight: run_drc: true set_text_variables: - name: 'rev' - command: "if [ $(git describe --tags | wc -w) -gt 0 ]; then git describe --tags | sed -e 's/\([r,R][0-9]\+\)*$//g'; else echo $CI_COMMIT_SHORT_SHA; fi" + command: 'if [ $(git describe --tags | wc -w) -gt 0 ]; then git describe --tags | sed -e "s/\([r,R][0-9]\+\)*$//g"; else echo $CI_COMMIT_SHORT_SHA; fi' - name: 'date' expand_kibot_patterns: true text: '%D' From 34a61a970f2101cc8f232bdd4e3986ea9122d8cb Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 28 Dec 2023 15:38:44 +1000 Subject: [PATCH 042/139] Trying to get the script in release to work --- default.kibot.yaml | 2 +- kibot-ci.yml | 60 ++++++++++++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 98ed39c..63bf35d 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -146,7 +146,7 @@ outputs: type: compress extends: _JLCPCB_compress options: - output: '%f_%r_JLC.%x' + output: '%f_JLC.%x' groups: diff --git a/kibot-ci.yml b/kibot-ci.yml index c649190..85a7fb6 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -10,7 +10,7 @@ variables: GIT_SUBMODULE_STRATEGY: normal GIT_SUBMODULE_FORCE_HTTPS: "true" # GIT_SUBMODULE_UPDATE_FLAGS: --remote --merge - PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/kicad/" + PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/kicad" stages: - gen_mech @@ -66,6 +66,7 @@ image: echo ${sch_arr[i-1]} python3 $CI_PROJECT_DIR/.gitlab/.scripts/orig.py ${dir_arr[i-1]} kibot -e ${dir_arr[i-1]}/${sch_arr[i-1]} -c $CI_PROJECT_DIR/.gitlab/default.kibot.yaml -d $CI_PROJECT_DIR/Fabrication/${dir_arr[i-1]} -s $SUFFIX + mv $CI_PROJECT_DIR/Fabrication/${dir_arr[i-1]}/*.zip Fabrication/ 2> /dev/null || true done - cd $CI_PROJECT_DIR @@ -105,6 +106,7 @@ image: git_tag: - | if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then + TAG=$(echo ${CI_COMMIT_MESSAGE} | tr -d \\n) echo "running git tag" git tag $CI_COMMIT_MESSAGE elif [[ $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" && "$CI_MERGE_REQUEST_TITLE" =~ [^a-zA-Z0-9.-_] ]]; then @@ -154,6 +156,9 @@ image: done fi + strip_tag: + - TAG=$(echo ${CI_COMMIT_MESSAGE} | tr -d \\n) + output_mech: stage: gen_mech artifacts: @@ -206,7 +211,6 @@ outputs_all: upload_job: stage: upload - image: curlimages/curl:latest needs: - job: outputs_all artifacts: true @@ -214,13 +218,23 @@ upload_job: - if: $CI_COMMIT_TAG when: never # Do not run this job when a tag is created manually - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch - variables: - FAB_COMM: "curl --header \"JOB-TOKEN: ${CI_JOB_TOKEN}\" --upload-file Fabrication/$d ${PACKAGE_REGISTRY_URL}/$d" script: + - !reference [.commands, strip_tag] + - apt-get update && apt-get -y install zip curl - | - for f in $(find Fabrication/ \! -type d) + zip -r Fabrication/All.zip Fabrication/ + for d in $(find Fabrication/* -maxdepth 0 -type d) do - curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $f ${PACKAGE_REGISTRY_URL}/$(filename $f) + zip=$d.zip + zip -r $zip $d + done + for d in $(find Fabrication/ -maxdepth 1 -name '*.zip') + do + b=$(basename $d) + f=$(echo "${b%.*}") + url=${PACKAGE_REGISTRY_URL}/$TAG/$f-$TAG.zip + echo "uploading: $d to $url" + curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file $d $url done artifacts: when: always @@ -228,7 +242,6 @@ upload_job: - Fabrication/**/* expire_in: 1 week - release_job: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest @@ -239,23 +252,24 @@ release_job: - if: $CI_COMMIT_TAG when: never # Do not run this job when a tag is created manually - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch - variables: - FAB_COMM: "echo \"--assets-link \"{\"name\":\"$d\",\"url\":\"${PACKAGE_REGISTRY_URL}/$CI_COMMIT_MESSAGE/$d\"}\" \\\"" script: + - !reference [.commands, strip_tag] + - apk add jq curl - | - echo "running release_job for $CI_COMMIT_MESSAGE" - echo "#!/bin/bash" >> fab.sh - echo "release-cli create --name \"Release $CI_COMMIT_MESSAGE\" --tag-name $CI_COMMIT_MESSAGE \\" >> fab.sh - echo "--assets-link \"{\"name\":\"All\",\"url\":\"${PACKAGE_REGISTRY_URL}/$CI_COMMIT_MESSAGE\"}\" \\" >> fab.sh - for d in $(ls -d */) + echo "running release_job for $TAG" + echo "#!/bin/sh" >> fab.sh + packid=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages | jq .[0].id) + echo "release-cli create --name \"Release $TAG\" --tag-name \"$TAG\" \\" >> fab.sh + cnt=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/$packid/package_files | jq length) + ids=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/$packid/package_files | jq .[].id) + names=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/$packid/package_files | jq .[].file_name) + i=1 + while [ "$i" -le $cnt ] do - echo "--assets-link \"{\"name\":\"$d\",\"url\":\"${PACKAGE_REGISTRY_URL}/$CI_COMMIT_MESSAGE/$d\"}\" \\" >> fab.sh + id=$(echo $ids | cut -d' ' -f $i) + name=$(echo $names | cut -d' ' -f $i) + echo " --assets-link \"{\\\"name\\\":\\\"$name\\\",\\\"url\\\":\\\"${CI_PROJECT_URL}/-/package_files/$id/download\\\"}\" \\" >> fab.sh + i=$(( i + 1 )) done - chmod u+x fab.sh - ./fab.sh - artifacts: - when: always - name: "$CI_PROJECT_TITLE-$CI_COMMIT_MESSAGE" - paths: - - Fabrication/**/* - expire_in: 1 week + chmod +x fab.sh + ./fab.sh || true From accd10e804a7f8580fccdd5f76696bb411755e5b Mon Sep 17 00:00:00 2001 From: ac Date: Sat, 30 Dec 2023 16:26:20 +1000 Subject: [PATCH 043/139] Attempt to filter folders --- kibot-ci.yml | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 85a7fb6..d2baac3 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -38,36 +38,45 @@ image: get_dirs: - FILES=$(find . -name *$SEARCH -not -path "./.gitlab/*") - | - if [[ $FILES == "" ]]; then - DIRS="" - else - DIRS=$(dirname $FILES) - fi + if [[ $FILES == "" ]]; then + DIRS="" + else + DIRS=$(dirname $FILES) + fi sch_from_pro: - 'SCHEMS=$(for f in $FILES ; do echo "${f%.*}.kicad_sch"; done)' - 'SCHEMS=$(for f in $SCHEMS ; do echo "${f##**/}"; done)' dir_arr: - !reference [.commands, get_dirs] - - END=$(wc -w <<< $DIRS) - - dir_arr=($DIRS) + - | + FILTERED=$(echo "") + for d in $DIRS + do + if [[ "$d" =~ ^[0-9]{4}-.*$ ]] + then + FILTERED=$(echo "$FILTERED $d") + fi + done + END=$(wc -w <<< $FILTERED) + dir_arr=($FILTERED) kibot: - 'SEARCH=".kicad_pro"' - !reference [.commands, dir_arr] - !reference [.commands, sch_from_pro] - sch_arr=($SCHEMS) - | - cd $CI_PROJECT_DIR - for i in $(seq 1 $END) - do - if [[ ${dir_arr[i-1]} == "./Frame" ]]; then - continue - fi - echo ${dir_arr[i-1]} - echo ${sch_arr[i-1]} - python3 $CI_PROJECT_DIR/.gitlab/.scripts/orig.py ${dir_arr[i-1]} - kibot -e ${dir_arr[i-1]}/${sch_arr[i-1]} -c $CI_PROJECT_DIR/.gitlab/default.kibot.yaml -d $CI_PROJECT_DIR/Fabrication/${dir_arr[i-1]} -s $SUFFIX - mv $CI_PROJECT_DIR/Fabrication/${dir_arr[i-1]}/*.zip Fabrication/ 2> /dev/null || true - done + cd $CI_PROJECT_DIR + for i in $(seq 1 $END) + do + if [[ ${dir_arr[i-1]} == "./Frame" ]]; then + continue + fi + echo ${dir_arr[i-1]} + echo ${sch_arr[i-1]} + python3 $CI_PROJECT_DIR/.gitlab/.scripts/orig.py ${dir_arr[i-1]} + kibot -e ${dir_arr[i-1]}/${sch_arr[i-1]} -c $CI_PROJECT_DIR/.gitlab/default.kibot.yaml -d $CI_PROJECT_DIR/Fabrication/${dir_arr[i-1]} -s $SUFFIX + mv $CI_PROJECT_DIR/Fabrication/${dir_arr[i-1]}/*.zip Fabrication/ 2> /dev/null || true + done - cd $CI_PROJECT_DIR panel: From 29a7560940d96bda423ada34567987bb6cfb3b2c Mon Sep 17 00:00:00 2001 From: ac Date: Sun, 31 Dec 2023 09:54:42 +1000 Subject: [PATCH 044/139] Trying to fix weird shell stuff --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index d2baac3..26578e1 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -57,7 +57,7 @@ image: FILTERED=$(echo "$FILTERED $d") fi done - END=$(wc -w <<< $FILTERED) + END=$(echo $FILTERED | wc -w) dir_arr=($FILTERED) kibot: - 'SEARCH=".kicad_pro"' From e421d658e3afc878dcbf64047daecde6aacb7429 Mon Sep 17 00:00:00 2001 From: ac Date: Sun, 31 Dec 2023 10:14:19 +1000 Subject: [PATCH 045/139] Filter file list as well --- kibot-ci.yml | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 26578e1..5d23cc4 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -36,7 +36,7 @@ image: get_files: - FILES=$(find . -name *$SEARCH -not -path "./.gitlab/*") get_dirs: - - FILES=$(find . -name *$SEARCH -not -path "./.gitlab/*") + - !reference [.commands, get_files] - | if [[ $FILES == "" ]]; then DIRS="" @@ -46,19 +46,28 @@ image: sch_from_pro: - 'SCHEMS=$(for f in $FILES ; do echo "${f%.*}.kicad_sch"; done)' - 'SCHEMS=$(for f in $SCHEMS ; do echo "${f##**/}"; done)' - dir_arr: - - !reference [.commands, get_dirs] - - | - FILTERED=$(echo "") - for d in $DIRS - do - if [[ "$d" =~ ^[0-9]{4}-.*$ ]] + get_dirs_filt: + - !reference [.commands, get_files] + - | + FILT_FILES="" + FILT_DIRS="" + for f in $FILES + do + dir=$(dirname $f) + echo $dir + if [[ "$dir" =~ ^.?\/?[0-9]{4}-.*$ ]] then - FILTERED=$(echo "$FILTERED $d") + FILT_FILES=$(echo "$FILT_FILES $f") + FILT_DIRS=$(echo "$FILT_DIRS $dir") fi done - END=$(echo $FILTERED | wc -w) - dir_arr=($FILTERED) + FILES=$FILT_FILES + DIRS=$FILT_DIRS + dir_arr: + - !reference [.commands, get_dirs_filt] + - | + END=$(echo $DIRS | wc -w) + dir_arr=($DIRS) kibot: - 'SEARCH=".kicad_pro"' - !reference [.commands, dir_arr] @@ -101,7 +110,7 @@ image: neo: - 'SEARCH=".kicad_pro"' - - !reference [.commands, get_dirs] + - !reference [.commands, get_dirs_filt] - | for d in $DIRS do From 2c582c23fc166d1bb44d825ec7b907ba04e163a5 Mon Sep 17 00:00:00 2001 From: ac Date: Sun, 14 Jan 2024 20:28:32 +1000 Subject: [PATCH 046/139] Added pre-push hook script for unlocking files on push --- pre-push | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 pre-push diff --git a/pre-push b/pre-push new file mode 100755 index 0000000..957611a --- /dev/null +++ b/pre-push @@ -0,0 +1,6 @@ +#!/bin/sh + +kimelon unlock all + +command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/pre-push'.\n"; exit 2; } +git lfs pre-push "$@" From c8c18d6c490567b9278ba5beedff8e55d72b952c Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 15 Jan 2024 09:50:31 +1000 Subject: [PATCH 047/139] Updated config to point to hooks directory in this repo, which contains the hook scripts --- .gitconfig | 2 ++ pre-push => hooks/pre-push | 0 2 files changed, 2 insertions(+) rename pre-push => hooks/pre-push (100%) diff --git a/.gitconfig b/.gitconfig index 5d8053b..9d65a4a 100644 --- a/.gitconfig +++ b/.gitconfig @@ -3,3 +3,5 @@ [submodule] recurse = true propogateBranches = true +[core] + hookspath = ".gitlab/hooks/" diff --git a/pre-push b/hooks/pre-push similarity index 100% rename from pre-push rename to hooks/pre-push From fc2ffba6dd451a9668b240dd400accb7ba920c7e Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 15 Jan 2024 11:40:02 +1000 Subject: [PATCH 048/139] Updated gitconfig to force lfs readonly locks on --- .gitconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitconfig b/.gitconfig index 9d65a4a..69ce823 100644 --- a/.gitconfig +++ b/.gitconfig @@ -3,5 +3,7 @@ [submodule] recurse = true propogateBranches = true +[lfs] + setlockablereadonly = true [core] hookspath = ".gitlab/hooks/" From 9f6584695d557309ecddef97bf7d246288147278 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 15 Jan 2024 15:21:27 +1000 Subject: [PATCH 049/139] Updated gitconfig to remove recursive pull as it doesn't respect branches --- .gitconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitconfig b/.gitconfig index 69ce823..e478c72 100644 --- a/.gitconfig +++ b/.gitconfig @@ -1,8 +1,7 @@ [status] submodulesummary = 1 -[submodule] - recurse = true - propogateBranches = true +[push] + recurseSubmodules = "on-demand" [lfs] setlockablereadonly = true [core] From ff8b1b79851cdd874c4243b1a2dbede2217f2316 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 17 Jan 2024 14:34:33 +1000 Subject: [PATCH 050/139] Updated client var in tcs wks --- tcs.kicad_wks | 2 +- tcs_default/tcs_default.kicad_pro | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tcs.kicad_wks b/tcs.kicad_wks index 35e77b2..28e0c33 100644 --- a/tcs.kicad_wks +++ b/tcs.kicad_wks @@ -31,7 +31,7 @@ ) (tbtext "In association with: Designworks" (name "") (pos 109 23) (comment "Comment 0") ) - (tbtext "Client: TCS JohnHuxley" (name "") (pos 109 26) (comment "Comment 1") + (tbtext "Client: ${client}" (name "") (pos 109 26) (comment "Comment 1") ) (tbtext "${COMMENT3}" (name "") (pos 109 29) (comment "Comment 2") ) diff --git a/tcs_default/tcs_default.kicad_pro b/tcs_default/tcs_default.kicad_pro index f23f7db..81e4e09 100644 --- a/tcs_default/tcs_default.kicad_pro +++ b/tcs_default/tcs_default.kicad_pro @@ -476,6 +476,7 @@ "text_variables": { "date": "", "rev": "", - "title": "" + "title": "", + "client": "TCS JOHN HUXLEY" } } From e819099ed526f4cd914d2d208a89b88824927726 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 17 Jan 2024 15:11:30 +1000 Subject: [PATCH 051/139] Updated name text vars in templates, and expand full_name var using kibot --- default.kibot.yaml | 3 +++ micromelon_default/micromelon_default.kicad_pro | 4 +++- tcs_default/tcs_default.kicad_pro | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 63bf35d..b4ed2ed 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -18,6 +18,9 @@ preflight: - name: 'name' expand_kibot_patterns: true command: 'echo $KIBOT_PCB_NAME | rev | cut -d"/" -f1 | rev | cut -d"-" -f1' + - name: 'title' + expand_kibot_patterns: true + command: 'echo $KIBOT_PCB_NAME | rev | cut -d"/" -f1 | rev | cut -d"." -f1 ' fill_zones: true ignore_unconnected: false diff --git a/micromelon_default/micromelon_default.kicad_pro b/micromelon_default/micromelon_default.kicad_pro index e0824aa..2898ad2 100644 --- a/micromelon_default/micromelon_default.kicad_pro +++ b/micromelon_default/micromelon_default.kicad_pro @@ -476,6 +476,8 @@ "text_variables": { "date": "", "rev": "", - "title": "" + "title": "", + "client": "", + "name": "" } } diff --git a/tcs_default/tcs_default.kicad_pro b/tcs_default/tcs_default.kicad_pro index 81e4e09..91f31ac 100644 --- a/tcs_default/tcs_default.kicad_pro +++ b/tcs_default/tcs_default.kicad_pro @@ -477,6 +477,7 @@ "date": "", "rev": "", "title": "", - "client": "TCS JOHN HUXLEY" + "client": "TCS JOHN HUXLEY", + "name": "" } } From f6bdbc19a1b8989f7035074fb565a6fceb7d8b59 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 17 Jan 2024 18:32:54 +1000 Subject: [PATCH 052/139] Debugging panelisation --- kibot-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 5d23cc4..60d169e 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -93,8 +93,10 @@ image: - !reference [.commands, get_dirs] - | cd $CI_PROJECT_DIR + echo "searching for panels" for d in $DIRS do + echo "found panel" echo $d JSON=$(find $d/*_panel.json) FILE=$(basename "${JSON}") From 9a899dc0b9bae38df13bebabd1abea62631312c8 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 17 Jan 2024 18:48:59 +1000 Subject: [PATCH 053/139] Stopped the folder filter from ignore panel folders --- kibot-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 60d169e..25af4b5 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -55,7 +55,7 @@ image: do dir=$(dirname $f) echo $dir - if [[ "$dir" =~ ^.?\/?[0-9]{4}-.*$ ]] + if [[ "$dir" =~ ^.?\/?[0-9]{4}-.*$ || "$dir" =~ .+_panel ]] then FILT_FILES=$(echo "$FILT_FILES $f") FILT_DIRS=$(echo "$FILT_DIRS $dir") @@ -93,7 +93,6 @@ image: - !reference [.commands, get_dirs] - | cd $CI_PROJECT_DIR - echo "searching for panels" for d in $DIRS do echo "found panel" @@ -228,6 +227,8 @@ outputs_all: - !reference [.commands, kibot] - !reference [.commands, neo] - !reference [.commands, merge_libs] + - ls Fabrication/ + upload_job: stage: upload From e1b0950042c3e63a41a7e26087fed0184a37f21d Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 17 Jan 2024 19:49:35 +1000 Subject: [PATCH 054/139] Ignore drill sizes in panel drc --- .scripts/post_panel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/.scripts/post_panel.py b/.scripts/post_panel.py index c0806be..bf46f4b 100644 --- a/.scripts/post_panel.py +++ b/.scripts/post_panel.py @@ -28,6 +28,7 @@ dest["board"]["design_settings"]["rule_severities"]["lib_footprint_mismatch"] = dest["board"]["design_settings"]["rule_severities"]["hole_near_hole"] = "ignore" dest["board"]["design_settings"]["rule_severities"]["silk_overlap"] = "ignore" dest["board"]["design_settings"]["rule_severities"]["silk_over_copper"] = "ignore" +dest["board"]["design_settings"]["rule_severities"]["drill_out_of_range"] = "ignore" # This one is just until kibot image is updated to 7.0.5 dest["board"]["design_settings"]["rule_severities"]["copper_sliver"] = "ignore" dest["net_settings"]["classes"] = src["net_settings"]["classes"] From 00d9551ad5e7625573d288c0a3e2983c9d6e0542 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 17 Jan 2024 20:12:58 +1000 Subject: [PATCH 055/139] Debugging panelisation errors --- .scripts/post_panel.py | 3 +++ kibot-ci.yml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.scripts/post_panel.py b/.scripts/post_panel.py index bf46f4b..c4e905d 100644 --- a/.scripts/post_panel.py +++ b/.scripts/post_panel.py @@ -5,6 +5,8 @@ import shutil proj = sys.argv[1] pcb = sys.argv[2] +print("Starting post_panel script") + dest_folder = '/'.join(proj.split('/')[:-1]) dest_name = proj.split('/')[-1].removesuffix(".kicad_pro") @@ -37,3 +39,4 @@ dest["net_settings"]["netclass_patterns"] = src["net_settings"]["netclass_patter with open(proj, mode="w") as json_file: json.dump(dest, json_file, indent=2) +print("Finished post_panel script") diff --git a/kibot-ci.yml b/kibot-ci.yml index 25af4b5..ead3455 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -101,7 +101,9 @@ image: FILE=$(basename "${JSON}") NAME=$(echo "${FILE%.json}") PCB=$(find $d/*.kicad_pcb) + echo "mkdring" mkdir $NAME + echo "panelising" kikit panelize -p $JSON $PCB $NAME/$NAME.kicad_pcb cp .gitlab/micromelon_default/micromelon_default.kicad_sch $NAME/$NAME.kicad_sch cp $d/fp-lib-table $NAME/ From 55d6698841790f05b4241d0e9accf65b89516a9d Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 13 Feb 2024 08:29:02 +1000 Subject: [PATCH 056/139] Updated default worksheet --- melon.kicad_wks | 4 ++-- micromelon_default/micromelon_default.kicad_pro | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/melon.kicad_wks b/melon.kicad_wks index b405758..afc5cb7 100644 --- a/melon.kicad_wks +++ b/melon.kicad_wks @@ -29,9 +29,9 @@ (tbtext "Sheet: ${SHEETPATH}" (name "") (pos 109 17)) (tbtext "Micromelon Robotics" (name "") (pos 109 20) (font bold) (comment "Company name") ) - (tbtext "In association with: ${COMMENT1}" (name "") (pos 109 23) (comment "Comment 0") + (tbtext "In association with: ${partner}" (name "") (pos 109 23) (comment "Comment 0") ) - (tbtext "Client: ${COMMENT2}" (name "") (pos 109 26) (comment "Comment 1") + (tbtext "Client: ${client}" (name "") (pos 109 26) (comment "Comment 1") ) (tbtext "${COMMENT3}" (name "") (pos 109 29) (comment "Comment 2") ) diff --git a/micromelon_default/micromelon_default.kicad_pro b/micromelon_default/micromelon_default.kicad_pro index 2898ad2..fd03554 100644 --- a/micromelon_default/micromelon_default.kicad_pro +++ b/micromelon_default/micromelon_default.kicad_pro @@ -478,6 +478,7 @@ "rev": "", "title": "", "client": "", + "partner": "", "name": "" } } From 04b0e8ba3d52feaac3225c7272aa6d55dd82fa61 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 19 Feb 2024 10:44:35 +1000 Subject: [PATCH 057/139] Updated kibot to 1.6.4 --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index ead3455..466e47c 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -19,7 +19,7 @@ stages: - release image: - name: ghcr.io/inti-cmnb/kicad7_auto:1.6.3 + name: ghcr.io/inti-cmnb/kicad7_auto:1.6.4 .main_rules: rules: From 42df3597ad9444f8ee5296672d066020fb12ef5a Mon Sep 17 00:00:00 2001 From: ac Date: Tue, 12 Mar 2024 10:08:33 +1000 Subject: [PATCH 058/139] WIP: footprint generation based off of text on 'User.Drawings' layer --- .scripts/foot_gen.py | 182 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 .scripts/foot_gen.py diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py new file mode 100644 index 0000000..2326499 --- /dev/null +++ b/.scripts/foot_gen.py @@ -0,0 +1,182 @@ +import sys +import os + +from pcbnew import * + +filename = sys.argv[1] + +pcb = LoadBoard(filename) + +ToUnits = ToMM +FromUnits = FromMM + +print("") +print("List drawings:") + + +# layers = pcb.GetEnabledLayers() +top_layer_id = pcb.GetLayerID("F.Cu") + + +new_foots = {} +foot_name = "" +foot_path = "" +for item in pcb.GetDrawings(): + if type(item) is PCB_TEXT and "User.Drawings" in item.GetLayerName(): + lines = str(item.GetText()).splitlines() + # Must have the correct header + if "Foot Pinout" not in lines[0]: + continue + if not lines[1].startswith("Name:"): + continue + foot_name = lines[1].split(":")[-1].strip() + if not lines[2].startswith("Path:"): + continue + foot_path = lines[2].split(":")[-1].strip() + for line in lines[3:]: + sp = line.split(':', 1) + if len(sp) != 2: + continue + # Path to substitue footprint + ref = sp[0] + foot_sp = sp[1].split(',') + foot = foot_sp[0].strip() + offset = (0,0) + # Optional offset tuple + if len(foot_sp) == 2: + offset = tuple(foot_sp[1]) + + new_foots[ref] = [foot, offset] + # pins = sp[1] + # pin_refs = [] + # for pin in pins.split(','): + # pin_refs.push(int(pin)) + + break + elif type(item) is PCB_TEXT: + print("Text: ", item.GetText()) + print("Layer: ", item.GetLayerName()) + +print("") +print("New Footprint List: ", new_foots) + +# Clear tracks +pcb.Tracks().clear() +# Clear zones +pcb.Zones().clear() +# Clear Drawings +pcb.Drawings().clear() + +# Keep only required foots +saved = [] +while len(pcb.Footprints()) > 1: + foot = pcb.Footprints().pop() + if foot.GetReference() in new_foots.keys(): + saved.append(foot) +# just in case +pcb.DeleteAllFootprints() +# Add them back +sorted_pads = [] +for foot in saved: + vals = new_foots[foot.GetReference()] + # Change the footprint + foot.SetFPIDAsString(vals[0]) + # Save the original postion of footprint + pads + orig_cent = foot.GetBoundingBox(False,False).Centre() + pads = [] + for pad in foot.Pads(): + pads.append([pad.GetCenter(), pad.GetNet()]) + + # Flip to other side + foot.SetLayerAndFlip(top_layer_id) + # Put back in original position with an offset + box = foot.GetBoundingBox(False,False) + new_cent = foot.GetBoundingBox(False,False).Centre() + cent_diff = orig_cent - new_cent + foot.SetX(foot.GetX() + cent_diff.x + vals[1][0]) + foot.SetY(foot.GetY() + cent_diff.y + vals[1][1]) + # Flip the net assignments of the pads + for pad in foot.Pads(): + sorted_pads.append(pad) + # Check position diff from old + # to new + new_cent = pad.GetCenter() + diffs = [] + for [old_cent,_] in pads: + diffs.append(new_cent - old_cent) + min_diff = min(diffs) + # If pad is within 0.05mm it's a match + if (min_diff.x**2 + min_diff.y**2)**0.5 < 50000: + # Set the net to what the old pad was + i = diffs.index(min_diff) + match_pad = pads[i][1:] + pad.SetNet(match_pad[0]) + + pcb.Add(foot) + + +# Sort by Y +sorted_pads.sort(key=lambda p: p.GetY()) + +box = pcb.GetBoundingBox() +brd_width = ToUnits(box.GetWidth()) +brd_height = ToUnits(box.GetHeight()) + +print("Box: ", box) +print("W: ", brd_width, "H: ", brd_height) + + +sys.path.append(os.path.join(sys.path[0],"../../../../../dev/kicad-footprint-generator")) + + +from KicadModTree import * +from KicadModTree.nodes.specialized.PadArray import PadArray + +footprint_name = "" + +# init kicad footprint +kicad_mod = Footprint(footprint_name, FootprintType.SMD) +kicad_mod.setDescription("A example footprint") +kicad_mod.setTags("example") + +# set general values +kicad_mod.append(Text(type='reference', text='REF**', at=[0,-3], layer='F.SilkS')) +kicad_mod.append(Text(type='value', text=footprint_name, at=[1.5,3], layer='F.Fab')) + +# create silscreen +kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.SilkS', width=0.15)) + +# create courtyard +kicad_mod.append(RectLine(start=[-brd_width/2 - 0.1,-brd_height/2 - 0.1], end=[brd_width/2 + 0.1,brd_height/2 + 0.1], layer='F.CrtYd', width=0.05, offset=2)) + +# create pads + +for x, pad in enumerate(sorted_pads): + cent = ToUnits(pad.GetCenter()) + pad_size = ToUnits(pad.GetSize()) + drill_size = ToUnits(pad.GetDrillSize()) + kicad_mod.append(Pad(number=x, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=list(cent), size=list(pad_size), drill=list(drill_size), layers=['*.Cu', '*.Mask', 'F.SilkS'])) +# kicad_mod.append(Pad(number=22, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, at=[3,0], size=[2,2], drill=1.2, layers=['*.Cu', '*.Mask', 'F.SilkS'])) +# +# kicad_mod.append(Pad(number=12, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[3,0], size=[2,2], drill=1.2, layers=['*.Cu', '*.Mask', 'F.SilkS'])) + +# add model +# kicad_mod.append(Model(filename="example.3dshapes/example_footprint.wrl" +# ,at=[0,0,0] +# ,scale=[1,1,1] +# ,rotate=[0,0,0])) + +# kicad_mod.append(PadArray(pincount=10,spacing=[1,-1],center=[0,0], initial=5, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[1,2], layers=["*.Cu"])) + +# output kicad model +#print(kicad_mod) + +# print render tree +#print(kicad_mod.getRenderTree()) +#print(kicad_mod.getCompleteRenderTree()) + +# write file +file_handler = KicadFileHandler(kicad_mod) +file_handler.writeFile('example_footprint.kicad_mod') + +SaveBoard("test/test.kicad_pcb", pcb) From e2cbf1696c50974ec10c7d9bbe55017bf209128f Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 12 Mar 2024 17:54:51 +1000 Subject: [PATCH 059/139] Finished initial implementation of the footprint generator. There is now a dependant submodule to produce footprints. --- .gitmodules | 3 + .scripts/foot_gen.py | 178 +++++++++++++++++++++++++------------- kibot-ci.yml | 2 +- kicad-footprint-generator | 1 + 4 files changed, 123 insertions(+), 61 deletions(-) create mode 100644 .gitmodules create mode 160000 kicad-footprint-generator diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f691bed --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "kicad-footprint-generator"] + path = kicad-footprint-generator + url = https://gitlab.com/kicad/libraries/kicad-footprint-generator.git diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index 2326499..a392155 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -1,26 +1,31 @@ import sys import os -from pcbnew import * +import pcbnew +from pcbnew import FOOTPRINT, FP_3DMODEL, VECTOR3D, FootprintLoad, FromMM, ToMM, LoadBoard, SaveBoard, PCB_TEXT filename = sys.argv[1] +os.mkdir("test") + pcb = LoadBoard(filename) -ToUnits = ToMM -FromUnits = FromMM - -print("") -print("List drawings:") +box = pcb.GetBoardEdgesBoundingBox() +brd_cent = box.GetCenter() +brd_width = ToMM(box.GetWidth()) +brd_height = ToMM(box.GetHeight()) +print("Box: ", box) +print("W: ", brd_width, "H: ", brd_height) # layers = pcb.GetEnabledLayers() top_layer_id = pcb.GetLayerID("F.Cu") - new_foots = {} +brd_outline = [] foot_name = "" foot_path = "" +z_offset = 0 for item in pcb.GetDrawings(): if type(item) is PCB_TEXT and "User.Drawings" in item.GetLayerName(): lines = str(item.GetText()).splitlines() @@ -33,7 +38,10 @@ for item in pcb.GetDrawings(): if not lines[2].startswith("Path:"): continue foot_path = lines[2].split(":")[-1].strip() - for line in lines[3:]: + if not lines[3].startswith("Z:"): + continue + z_offset = float(lines[3].split(":")[-1].strip()) + for line in lines[4:]: sp = line.split(':', 1) if len(sp) != 2: continue @@ -53,19 +61,27 @@ for item in pcb.GetDrawings(): # pin_refs.push(int(pin)) break - elif type(item) is PCB_TEXT: - print("Text: ", item.GetText()) - print("Layer: ", item.GetLayerName()) + elif "Edge.Cuts" in item.GetLayerName(): + brd_outline.append(item) + # print("Text: ", item.GetText()) + # print("Layer: ", item.GetLayerName()) print("") print("New Footprint List: ", new_foots) + +if len(new_foots) == 0: + exit(0) + # Clear tracks pcb.Tracks().clear() # Clear zones pcb.Zones().clear() # Clear Drawings pcb.Drawings().clear() +# Add back in the outline +for d in brd_outline: + pcb.Drawings().append(d) # Keep only required foots saved = [] @@ -76,107 +92,149 @@ while len(pcb.Footprints()) > 1: # just in case pcb.DeleteAllFootprints() # Add them back -sorted_pads = [] +sorted_foots = [] for foot in saved: vals = new_foots[foot.GetReference()] # Change the footprint - foot.SetFPIDAsString(vals[0]) + path_split = vals[0].split(':') + folder = sys.path[0] + "/../../libs/melonlib/"+ path_split[0] + ".pretty" + load_foot = FootprintLoad(folder, path_split[1]) + # foot.SetFPIDAsString(vals[0]) # Save the original postion of footprint + pads orig_cent = foot.GetBoundingBox(False,False).Centre() + orig_orient = foot.GetOrientation() pads = [] for pad in foot.Pads(): - pads.append([pad.GetCenter(), pad.GetNet()]) + pads.append([pad.GetNumber(), pad.GetCenter(), pad.GetNet()]) - # Flip to other side - foot.SetLayerAndFlip(top_layer_id) + # # Flip to other side + # foot.SetLayerAndFlip(top_layer_id) # Put back in original position with an offset - box = foot.GetBoundingBox(False,False) - new_cent = foot.GetBoundingBox(False,False).Centre() + load_foot.SetOrientation(orig_orient) + new_cent = load_foot.GetBoundingBox(False,False).Centre() cent_diff = orig_cent - new_cent - foot.SetX(foot.GetX() + cent_diff.x + vals[1][0]) - foot.SetY(foot.GetY() + cent_diff.y + vals[1][1]) + load_foot.SetX(load_foot.GetX() + cent_diff.x + vals[1][0]) + load_foot.SetY(load_foot.GetY() + cent_diff.y + vals[1][1]) # Flip the net assignments of the pads - for pad in foot.Pads(): - sorted_pads.append(pad) + pad_map = {} + for pad in load_foot.Pads(): # Check position diff from old # to new new_cent = pad.GetCenter() diffs = [] - for [old_cent,_] in pads: + for [_, old_cent,_] in pads: diffs.append(new_cent - old_cent) min_diff = min(diffs) # If pad is within 0.05mm it's a match if (min_diff.x**2 + min_diff.y**2)**0.5 < 50000: # Set the net to what the old pad was i = diffs.index(min_diff) - match_pad = pads[i][1:] + match_num = pads[i][0] + match_pad = pads[i][2:] pad.SetNet(match_pad[0]) + pad_map[pad.GetNumber()] = match_num - pcb.Add(foot) + sorted_foots.append([load_foot, pad_map]) + pcb.Add(load_foot) # Sort by Y -sorted_pads.sort(key=lambda p: p.GetY()) +sorted_foots.sort(key=lambda foot: foot[0].GetY()) -box = pcb.GetBoundingBox() -brd_width = ToUnits(box.GetWidth()) -brd_height = ToUnits(box.GetHeight()) +# Export the step file +os.system("kicad-cli pcb export step -f --subst-models --user-origin " + str(ToMM(brd_cent.x)) + "x" + str(ToMM(brd_cent.y)) + "mm -o /tmp/dummy.step " + sys.argv[1]) -print("Box: ", box) -print("W: ", brd_width, "H: ", brd_height) +# Import the 3d model of the actual PCB +dummy = FOOTPRINT(pcb) +dummy.SetPosition(brd_cent) +dummy_model = FP_3DMODEL() +dummy_model.m_Filename = "/tmp/dummy.step" +dummy_model.m_Offset = VECTOR3D(0.0, 0.0, z_offset) +dummy.Add3DModel(dummy_model) +pcb.Add(dummy) + +# # Set the pcb thickness to 0 +# des_sett = pcb.GetDesignSettings() +# stackup = des_sett.GetStackupDescriptor() + +# Save and export step of board + mating connectors +SaveBoard("test/test.kicad_pcb", pcb) +final_model_path = sys.path[0] + "/../../libs/melon3d/" + foot_path + ".3dshapes/" + foot_name + ".step" +os.system("kicad-cli pcb export step -f --subst-models --user-origin " + str(ToMM(brd_cent.x)) + "x" + str(ToMM(brd_cent.y)) + "mm -o " + final_model_path + " test/test.kicad_pcb") -sys.path.append(os.path.join(sys.path[0],"../../../../../dev/kicad-footprint-generator")) +# Generate footprint +sys.path.append(os.path.join(sys.path[0],"../kicad-footprint-generator")) from KicadModTree import * from KicadModTree.nodes.specialized.PadArray import PadArray -footprint_name = "" - # init kicad footprint -kicad_mod = Footprint(footprint_name, FootprintType.SMD) +kicad_mod = Footprint(foot_name, FootprintType.SMD) kicad_mod.setDescription("A example footprint") kicad_mod.setTags("example") # set general values kicad_mod.append(Text(type='reference', text='REF**', at=[0,-3], layer='F.SilkS')) -kicad_mod.append(Text(type='value', text=footprint_name, at=[1.5,3], layer='F.Fab')) +kicad_mod.append(Text(type='value', text=foot_name, at=[1.5,3], layer='F.Fab')) # create silscreen kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.SilkS', width=0.15)) # create courtyard -kicad_mod.append(RectLine(start=[-brd_width/2 - 0.1,-brd_height/2 - 0.1], end=[brd_width/2 + 0.1,brd_height/2 + 0.1], layer='F.CrtYd', width=0.05, offset=2)) +kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.CrtYd', width=0.05, offset=0.5)) # create pads +pad_cnt = 0 +for [foot, pad_map] in sorted_foots: + for pad in foot.Pads(): + cent = ToMM(pad.GetCenter() - brd_cent) + pad_size = ToMM(pad.GetSize()) + drill_size = ToMM(pad.GetDrillSize()) + curr_pad_num = pad.GetNumber() + attr_type = pad.GetAttribute() + shape_type = pad.GetShape() + + pad_type = Pad.TYPE_THT + pad_layers = Pad.LAYERS_THT + if attr_type == pcbnew.PAD_ATTRIB_SMD: + pad_type = Pad.TYPE_SMT + pad_layers = Pad.LAYERS_SMT + elif attr_type == pcbnew.PAD_ATTRIB_NPTH: + pad_type = Pad.TYPE_NPTH + pad_layers = Pad.LAYERS_NPTH + elif attr_type == pcbnew.PAD_ATTRIB_CONN: + pad_type = Pad.TYPE_CONNECT + pad_layers = Pad.LAYERS_NPTH -for x, pad in enumerate(sorted_pads): - cent = ToUnits(pad.GetCenter()) - pad_size = ToUnits(pad.GetSize()) - drill_size = ToUnits(pad.GetDrillSize()) - kicad_mod.append(Pad(number=x, type=Pad.TYPE_THT, shape=Pad.SHAPE_RECT, at=list(cent), size=list(pad_size), drill=list(drill_size), layers=['*.Cu', '*.Mask', 'F.SilkS'])) -# kicad_mod.append(Pad(number=22, type=Pad.TYPE_THT, shape=Pad.SHAPE_CIRCLE, at=[3,0], size=[2,2], drill=1.2, layers=['*.Cu', '*.Mask', 'F.SilkS'])) -# -# kicad_mod.append(Pad(number=12, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, at=[3,0], size=[2,2], drill=1.2, layers=['*.Cu', '*.Mask', 'F.SilkS'])) + pad_shape = Pad.SHAPE_RECT + if shape_type == pcbnew.PAD_SHAPE_CIRCLE: + pad_shape = Pad.SHAPE_CIRCLE + elif shape_type == pcbnew.PAD_SHAPE_OVAL: + pad_shape = Pad.SHAPE_OVAL + elif shape_type == pcbnew.PAD_SHAPE_CHAMFERED_RECT: + pad_shape = Pad.SHAPE_TRAPEZE + elif shape_type == pcbnew.PAD_SHAPE_ROUNDRECT: + pad_shape = Pad.SHAPE_ROUNDRECT + elif shape_type == pcbnew.PAD_SHAPE_CUSTOM: + pad_shape = Pad.SHAPE_CUSTOM + + kicad_mod.append(Pad(number=pad_cnt + int(pad_map[curr_pad_num]), type=pad_type, shape=pad_shape, at=list(cent), size=list(pad_size), drill=list(drill_size), layers=pad_layers)) + pad_cnt += len(foot.Pads()) -# add model -# kicad_mod.append(Model(filename="example.3dshapes/example_footprint.wrl" -# ,at=[0,0,0] -# ,scale=[1,1,1] -# ,rotate=[0,0,0])) -# kicad_mod.append(PadArray(pincount=10,spacing=[1,-1],center=[0,0], initial=5, increment=2, type=Pad.TYPE_SMT, shape=Pad.SHAPE_RECT, size=[1,2], layers=["*.Cu"])) - -# output kicad model -#print(kicad_mod) - -# print render tree -#print(kicad_mod.getRenderTree()) -#print(kicad_mod.getCompleteRenderTree()) +final_model_path = "${KIPRJMOD}/../libs/melon3d/" + foot_path + ".3dshapes/" + foot_name + ".step" +kicad_mod.append(Model(filename=final_model_path + ,at=[0,0,-1.6] + ,scale=[1,1,1] + ,rotate=[0,0,0])) # write file file_handler = KicadFileHandler(kicad_mod) -file_handler.writeFile('example_footprint.kicad_mod') +final_foot_path = sys.path[0] + "/../../libs/melonlib/" + foot_path + ".pretty/" + foot_name + ".kicad_mod" +file_handler.writeFile(final_foot_path) -SaveBoard("test/test.kicad_pcb", pcb) +import shutil + +shutil.rmtree("test") diff --git a/kibot-ci.yml b/kibot-ci.yml index 466e47c..ae3e6d9 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -7,7 +7,7 @@ workflow: variables: GIT_STRATEGY: clone - GIT_SUBMODULE_STRATEGY: normal + GIT_SUBMODULE_STRATEGY: recursive GIT_SUBMODULE_FORCE_HTTPS: "true" # GIT_SUBMODULE_UPDATE_FLAGS: --remote --merge PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/kicad" diff --git a/kicad-footprint-generator b/kicad-footprint-generator new file mode 160000 index 0000000..7d3e9fc --- /dev/null +++ b/kicad-footprint-generator @@ -0,0 +1 @@ +Subproject commit 7d3e9fcf8930e452e68a66f008ad319126d0a9b0 From e927efbc22ee8b9d4fa6c780c4414ae1503826de Mon Sep 17 00:00:00 2001 From: ac Date: Wed, 13 Mar 2024 22:17:22 +1000 Subject: [PATCH 060/139] Update footprint gen script to better deal with mounting holes --- .scripts/foot_gen.py | 51 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index a392155..89d8c83 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -47,12 +47,16 @@ for item in pcb.GetDrawings(): continue # Path to substitue footprint ref = sp[0] - foot_sp = sp[1].split(',') + foot_sp = sp[1].split(';') foot = foot_sp[0].strip() offset = (0,0) # Optional offset tuple if len(foot_sp) == 2: - offset = tuple(foot_sp[1]) + print("Foot sp: ", foot_sp) + offset = foot_sp[1].strip(" ()").split(',') + print("Offset: ", offset) + offset[0] = FromMM(float(offset[0])) + offset[1] = FromMM(float(offset[1])) new_foots[ref] = [foot, offset] # pins = sp[1] @@ -118,6 +122,8 @@ for foot in saved: # Flip the net assignments of the pads pad_map = {} for pad in load_foot.Pads(): + if len(pad.GetNumber()) == 0: + continue # Check position diff from old # to new new_cent = pad.GetCenter() @@ -133,6 +139,11 @@ for foot in saved: match_pad = pads[i][2:] pad.SetNet(match_pad[0]) pad_map[pad.GetNumber()] = match_num + elif "mounting" in str(foot.GetKeywords()).lower(): + match_num = pads[0][0] + match_pad = pads[0][2:] + pad.SetNet(match_pad[0]) + pad_map[pad.GetNumber()] = match_num sorted_foots.append([load_foot, pad_map]) pcb.Add(load_foot) @@ -186,8 +197,17 @@ kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,b kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.CrtYd', width=0.05, offset=0.5)) # create pads +print(sorted_foots) pad_cnt = 0 for [foot, pad_map] in sorted_foots: + mounting_flag = "mounting" in str(foot.GetKeywords()).lower() + custom_paste_flag = False + if mounting_flag: + for pad in foot.Pads(): + if pad.IsAperturePad(): + custom_paste_flag = True + + real_pads = 0 for pad in foot.Pads(): cent = ToMM(pad.GetCenter() - brd_cent) pad_size = ToMM(pad.GetSize()) @@ -200,7 +220,10 @@ for [foot, pad_map] in sorted_foots: pad_layers = Pad.LAYERS_THT if attr_type == pcbnew.PAD_ATTRIB_SMD: pad_type = Pad.TYPE_SMT - pad_layers = Pad.LAYERS_SMT + if custom_paste_flag: + pad_layers = ["F.Cu", "F.Mask"] + else: + pad_layers = Pad.LAYERS_SMT elif attr_type == pcbnew.PAD_ATTRIB_NPTH: pad_type = Pad.TYPE_NPTH pad_layers = Pad.LAYERS_NPTH @@ -208,6 +231,10 @@ for [foot, pad_map] in sorted_foots: pad_type = Pad.TYPE_CONNECT pad_layers = Pad.LAYERS_NPTH + if pad.IsAperturePad(): + pad_layers = ["F.Paste"] + + primitives = [] pad_shape = Pad.SHAPE_RECT if shape_type == pcbnew.PAD_SHAPE_CIRCLE: pad_shape = Pad.SHAPE_CIRCLE @@ -219,9 +246,21 @@ for [foot, pad_map] in sorted_foots: pad_shape = Pad.SHAPE_ROUNDRECT elif shape_type == pcbnew.PAD_SHAPE_CUSTOM: pad_shape = Pad.SHAPE_CUSTOM - - kicad_mod.append(Pad(number=pad_cnt + int(pad_map[curr_pad_num]), type=pad_type, shape=pad_shape, at=list(cent), size=list(pad_size), drill=list(drill_size), layers=pad_layers)) - pad_cnt += len(foot.Pads()) + # print(dir(pad.GetPrimitives())) + # for prim in pad.GetPrimitives(): + # shape = prim.GetEffectiveShape() + # print("Shape: ", shape) + + pad_number = "" + if len(pad.GetNumber()) > 0: + pad_number = pad_cnt + int(pad_map[curr_pad_num]) + + final_pad = Pad(number=pad_number, type=pad_type, shape=pad_shape, at=list(cent), size=list(pad_size), drill=list(drill_size), layers=pad_layers) + for prim in primitives: + final_pad.addPrimitive(prim) + kicad_mod.append(final_pad) + real_pads += len(pad.GetNumber()) > 0 + pad_cnt += real_pads final_model_path = "${KIPRJMOD}/../libs/melon3d/" + foot_path + ".3dshapes/" + foot_name + ".step" From 06a2385777fea0bdbebf0fa0c415ffd2f5132675 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 14 Mar 2024 13:22:38 +1000 Subject: [PATCH 061/139] Foot gen script now sorts footprints by the order they are listed in the pcb text --- .scripts/foot_gen.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index 89d8c83..69054a9 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -93,6 +93,7 @@ while len(pcb.Footprints()) > 1: foot = pcb.Footprints().pop() if foot.GetReference() in new_foots.keys(): saved.append(foot) +saved.sort(key=lambda foot: list(new_foots.keys()).index(foot.GetReference())) # just in case pcb.DeleteAllFootprints() # Add them back @@ -149,8 +150,8 @@ for foot in saved: pcb.Add(load_foot) -# Sort by Y -sorted_foots.sort(key=lambda foot: foot[0].GetY()) +# # Sort by Y +# sorted_foots.sort(key=lambda foot: foot[0].GetY()) # Export the step file os.system("kicad-cli pcb export step -f --subst-models --user-origin " + str(ToMM(brd_cent.x)) + "x" + str(ToMM(brd_cent.y)) + "mm -o /tmp/dummy.step " + sys.argv[1]) From 76103dbc9ef3ddc20b182c61660e8da31a89675a Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 15 Mar 2024 10:08:24 +1000 Subject: [PATCH 062/139] Updated foot gen to look for primitive instructions in footprint --- .scripts/foot_gen.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index 69054a9..cbcf50c 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -22,7 +22,7 @@ print("W: ", brd_width, "H: ", brd_height) top_layer_id = pcb.GetLayerID("F.Cu") new_foots = {} -brd_outline = [] +brd_drawings = [] foot_name = "" foot_path = "" z_offset = 0 @@ -31,6 +31,7 @@ for item in pcb.GetDrawings(): lines = str(item.GetText()).splitlines() # Must have the correct header if "Foot Pinout" not in lines[0]: + brd_drawings.append(item) continue if not lines[1].startswith("Name:"): continue @@ -66,7 +67,7 @@ for item in pcb.GetDrawings(): break elif "Edge.Cuts" in item.GetLayerName(): - brd_outline.append(item) + brd_drawings.append(item) # print("Text: ", item.GetText()) # print("Layer: ", item.GetLayerName()) @@ -84,7 +85,7 @@ pcb.Zones().clear() # Clear Drawings pcb.Drawings().clear() # Add back in the outline -for d in brd_outline: +for d in brd_drawings: pcb.Drawings().append(d) # Keep only required foots @@ -236,6 +237,7 @@ for [foot, pad_map] in sorted_foots: pad_layers = ["F.Paste"] primitives = [] + pad_number = pad.GetNumber() pad_shape = Pad.SHAPE_RECT if shape_type == pcbnew.PAD_SHAPE_CIRCLE: pad_shape = Pad.SHAPE_CIRCLE @@ -247,13 +249,20 @@ for [foot, pad_map] in sorted_foots: pad_shape = Pad.SHAPE_ROUNDRECT elif shape_type == pcbnew.PAD_SHAPE_CUSTOM: pad_shape = Pad.SHAPE_CUSTOM + for d in foot.GraphicalItems(): + print("Item: ", d) + if type(d) is PCB_TEXT and "User.Drawings" in d.GetLayerName(): + txt_sp = d.GetText().split(':',1) + if pad_number != txt_sp[0]: + continue + primitives.append(exec(txt_sp[1])) + # print(dir(pad.GetPrimitives())) # for prim in pad.GetPrimitives(): # shape = prim.GetEffectiveShape() # print("Shape: ", shape) - pad_number = "" - if len(pad.GetNumber()) > 0: + if len(pad_number) > 0: pad_number = pad_cnt + int(pad_map[curr_pad_num]) final_pad = Pad(number=pad_number, type=pad_type, shape=pad_shape, at=list(cent), size=list(pad_size), drill=list(drill_size), layers=pad_layers) From f41437bd6afa26b676f10acd562d7f543be48a77 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 15 Mar 2024 11:58:41 +1000 Subject: [PATCH 063/139] Made smt pad offsets work by forking the generator repo --- .gitmodules | 3 ++- .scripts/foot_gen.py | 19 ++++++++++++------- kicad-footprint-generator | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.gitmodules b/.gitmodules index f691bed..02916e8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,4 @@ [submodule "kicad-footprint-generator"] path = kicad-footprint-generator - url = https://gitlab.com/kicad/libraries/kicad-footprint-generator.git + url = git@gitlab.com:acmelon/kicad-footprint-generator.git + branch = offset_fix diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index cbcf50c..3ea36d5 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -175,7 +175,6 @@ SaveBoard("test/test.kicad_pcb", pcb) final_model_path = sys.path[0] + "/../../libs/melon3d/" + foot_path + ".3dshapes/" + foot_name + ".step" os.system("kicad-cli pcb export step -f --subst-models --user-origin " + str(ToMM(brd_cent.x)) + "x" + str(ToMM(brd_cent.y)) + "mm -o " + final_model_path + " test/test.kicad_pcb") - # Generate footprint sys.path.append(os.path.join(sys.path[0],"../kicad-footprint-generator")) @@ -217,6 +216,8 @@ for [foot, pad_map] in sorted_foots: curr_pad_num = pad.GetNumber() attr_type = pad.GetAttribute() shape_type = pad.GetShape() + offset = pad.GetOffset() + pad_type = Pad.TYPE_THT pad_layers = Pad.LAYERS_THT @@ -250,12 +251,14 @@ for [foot, pad_map] in sorted_foots: elif shape_type == pcbnew.PAD_SHAPE_CUSTOM: pad_shape = Pad.SHAPE_CUSTOM for d in foot.GraphicalItems(): - print("Item: ", d) - if type(d) is PCB_TEXT and "User.Drawings" in d.GetLayerName(): + if type(d) is pcbnew.FP_TEXT and "User.Drawings" in d.GetLayerName(): txt_sp = d.GetText().split(':',1) if pad_number != txt_sp[0]: continue - primitives.append(exec(txt_sp[1])) + print("Item:", txt_sp[1].strip()) + exec("tmp = " + txt_sp[1].strip()) + primitives.append(tmp) + # primitives.append(Arc(center=[0, 0], start=[-2.95, 0], width=1.5, angle=360, layer='F.Cu')) # print(dir(pad.GetPrimitives())) # for prim in pad.GetPrimitives(): @@ -265,9 +268,11 @@ for [foot, pad_map] in sorted_foots: if len(pad_number) > 0: pad_number = pad_cnt + int(pad_map[curr_pad_num]) - final_pad = Pad(number=pad_number, type=pad_type, shape=pad_shape, at=list(cent), size=list(pad_size), drill=list(drill_size), layers=pad_layers) - for prim in primitives: - final_pad.addPrimitive(prim) + # primitives = [Arc(center=[0, 0], start=[-2.95, 0], width=1.5, angle=360, layer='F.Cu')] + print("offset: ", [ToMM(offset.x), ToMM(offset.y)]) + final_pad = Pad(number=pad_number, type=pad_type, shape=pad_shape, at=list(cent), size=list(pad_size), drill=list(drill_size), offset=list(ToMM(offset)), layers=pad_layers, primitives=primitives) + # for prim in primitives: + # final_pad.addPrimitive(prim) kicad_mod.append(final_pad) real_pads += len(pad.GetNumber()) > 0 pad_cnt += real_pads diff --git a/kicad-footprint-generator b/kicad-footprint-generator index 7d3e9fc..4fb76cc 160000 --- a/kicad-footprint-generator +++ b/kicad-footprint-generator @@ -1 +1 @@ -Subproject commit 7d3e9fcf8930e452e68a66f008ad319126d0a9b0 +Subproject commit 4fb76cc408a3e6016f278fbe076accd4ac30761b From 5609c4de8024d3ae0bd63ae699ea2f228af03859 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 15 Mar 2024 13:34:56 +1000 Subject: [PATCH 064/139] Added spoke angle support --- kicad-footprint-generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kicad-footprint-generator b/kicad-footprint-generator index 4fb76cc..a1dcd54 160000 --- a/kicad-footprint-generator +++ b/kicad-footprint-generator @@ -1 +1 @@ -Subproject commit 4fb76cc408a3e6016f278fbe076accd4ac30761b +Subproject commit a1dcd5451f96b4fd869e7d70e7aa880e07541e75 From cc806b7c88b56b70ff756f87a8ac92aa161cd678 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 15 Mar 2024 16:09:25 +1000 Subject: [PATCH 065/139] Foot gen: updated silkscreen of board outline to not intersect with the courtyards of any parts --- .scripts/foot_gen.py | 132 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 4 deletions(-) diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index 3ea36d5..7803c23 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -1,3 +1,4 @@ +from copy import deepcopy import sys import os @@ -70,6 +71,10 @@ for item in pcb.GetDrawings(): brd_drawings.append(item) # print("Text: ", item.GetText()) # print("Layer: ", item.GetLayerName()) + elif "F.Courtyard" in item.GetLayerName(): + brd_drawings.append(item) + # print("Text: ", item.GetText()) + # print("Layer: ", item.GetLayerName()) print("") print("New Footprint List: ", new_foots) @@ -191,22 +196,88 @@ kicad_mod.setTags("example") kicad_mod.append(Text(type='reference', text='REF**', at=[0,-3], layer='F.SilkS')) kicad_mod.append(Text(type='value', text=foot_name, at=[1.5,3], layer='F.Fab')) -# create silscreen -kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.SilkS', width=0.15)) - # create courtyard -kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.CrtYd', width=0.05, offset=0.5)) +# for [foot, pad_map] in sorted_foots: + +# kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.CrtYd', width=0.05, offset=0.5)) # create pads print(sorted_foots) +keepouts = [] pad_cnt = 0 for [foot, pad_map] in sorted_foots: + local_box = foot.GetBoundingBox(False,False) + local_cent = ToMM(local_box.GetCenter() - brd_cent) + local_size = ToMM(local_box.GetSize()) + print("Bounding: ", local_cent, local_size) + keepouts.append([local_cent, local_size]) mounting_flag = "mounting" in str(foot.GetKeywords()).lower() custom_paste_flag = False if mounting_flag: for pad in foot.Pads(): if pad.IsAperturePad(): custom_paste_flag = True + # size = foot.GetBoundingBox(False,False).GetSize() + # cent = foot.GetCenter() - brd_cent + # x_flag = abs(cent.x) - brd_width/2 > -size.x/2 + # y_flag = abs(cent.y) - brd_height/2 > -size.y/2 + # if x_flag or y_flag: + # shape_type = foot.GetEffectiveShape() + # cent_mm = ToMM(cent) + # size_mm = ToMM(size) + # start_x = brd_width/2 + # start_y = brd_height/2 + # if cent.x < 0: + # start_x = -1*start_x + # if cent.y < 0: + # start_y = -1*start_y + # if not x_flag: + # start_x = cent_mm[0] + # if not y_flag: + # start_y = cent_mm[1] + # print("Silk: ", cent_mm, size_mm) + # if shape_type == pcbnew.SHAPE_T_RECT: + # start = [start_x, start_y + size_mm[1]/2] + # end = [start[0] + size_mm[0]/2, start[1]] + # kicad_mod.append(Line(start=start, end=end, layer='F.Silkscreen', width=0.05)) + # start = [end[0], end[1]] + # end = [start[0], start[1] - size[1]] + # kicad_mod.append(Line(start=start, end=end, layer='F.Silkscreen', width=0.05)) + # start = [end[0], end[1]] + # end = [start[0] - size[0]/2, start[1]] + # kicad_mod.append(Line(start=start, end=end, layer='F.Silkscreen', width=0.05)) + # start = [cent_mm[0] - size_mm[0], cent_mm[1] - size_mm[1]] + # end = [cent_mm[0] + size_mm[0], cent_mm[1] + size_mm[1]] + # kicad_mod.append(RectLine(start=start, end=end, layer='F.Silkscreen', width=0.05, offset=0.2)) + # elif shape_type == pcbnew.SHAPE_T_CIRCLE: + # start = [cent_mm[0], cent_mm[1] + size_mm[1]/2] + # end = [start[0], start[1]] + # radius = size.x/2 + # kicad_mod.append(Arc(center=cent, start=radius, layer='F.Silkscreen', width=0.05)) + # radius = size_mm[0]/2 + 0.2 + # kicad_mod.append(Circle(center=cent_mm, radius=radius, layer='F.Silkscreen', width=0.05)) + + for d in foot.GraphicalItems(): + if type(d) is pcbnew.FP_SHAPE and "F.Courtyard" in d.GetLayerName(): + shape_type = d.GetShape() + cent = d.GetCenter() - brd_cent + print("Courtyard: ", cent, shape_type) + if shape_type == pcbnew.SHAPE_T_SEGMENT: + start = d.GetStart() - brd_cent + end = d.GetEnd() - brd_cent + print("Seg: ", ToMM(start), ToMM(end)) + kicad_mod.append(Line(start=ToMM(start), end=ToMM(end), layer='F.CrtYd', width=0.05)) + elif shape_type == pcbnew.SHAPE_T_RECT: + start = d.GetStart() - brd_cent + end = d.GetEnd() - brd_cent + print("Rect: ", ToMM(start), ToMM(end)) + kicad_mod.append(RectLine(start=ToMM(start), end=ToMM(end), layer='F.CrtYd', width=0.05)) + elif shape_type == pcbnew.SHAPE_T_CIRCLE: + radius = ToMM(d.GetRadius()) + cent = ToMM(cent) + print("Circ: ", cent, radius) + kicad_mod.append(Circle(center=cent, radius=radius, layer='F.CrtYd', width=0.05)) + real_pads = 0 for pad in foot.Pads(): @@ -278,6 +349,59 @@ for [foot, pad_map] in sorted_foots: pad_cnt += real_pads +# create silkscreen +print("keepouts: ", keepouts) +corners = [[-brd_width/2, -brd_height/2], [-brd_width/2, brd_height/2], [brd_width/2, brd_height/2], [brd_width/2, -brd_height/2]] +for i in range(len(corners)): + if i == len(corners)-1: + j = 0 + else: + j = i+1 + start = deepcopy(corners[i]) + end = deepcopy(start) + x_dir = True + if corners[i][0] == corners[j][0]: + x_dir = False + sign = -1 + if corners[j][not x_dir] > corners[i][not x_dir]: + sign = 1 + # Find intersections with keepouts + intersects = [] + if x_dir: + for k in keepouts: + if abs(start[1] - k[0][1]) < k[1][1]/2: + intersects.append(k) + intersects.sort(key=lambda k: abs(start[0] - k[0][0])) + else: + for k in keepouts: + if abs(start[0] - k[0][0]) < k[1][0]/2: + intersects.append(k) + intersects.sort(key=lambda k: abs(start[1] - k[0][1])) + + + print("Start: ", start) + print("end: ", corners[j]) + print("Flag: ", x_dir) + print("intersects: ", intersects) + for intersect in intersects: + if x_dir: + end[0] = intersect[0][0] - sign * intersect[1][0]/2 + else: + end[1] = intersect[0][1] - sign * intersect[1][1]/2 + + print("Silk: ", start, end) + kicad_mod.append(Line(start=start, end=end, layer='F.SilkS', width=0.1)) + if x_dir: + start[0] = intersect[0][0] + sign * intersect[1][0]/2 + else: + start[1] = intersect[0][1] + sign * intersect[1][1]/2 + + kicad_mod.append(Line(start=start, end=corners[j], layer='F.SilkS', width=0.1)) + + +# kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.SilkS', width=0.15)) + + final_model_path = "${KIPRJMOD}/../libs/melon3d/" + foot_path + ".3dshapes/" + foot_name + ".step" kicad_mod.append(Model(filename=final_model_path ,at=[0,0,-1.6] From e55641095c99a1a868688ae8574a8e88a56d207d Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 15 Mar 2024 18:25:52 +1000 Subject: [PATCH 066/139] Foot gen: support ignoring corners if part overlaps them --- .scripts/foot_gen.py | 57 ++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index 7803c23..23d7911 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -359,44 +359,49 @@ for i in range(len(corners)): j = i+1 start = deepcopy(corners[i]) end = deepcopy(start) - x_dir = True + y_dir = False if corners[i][0] == corners[j][0]: - x_dir = False + y_dir = True sign = -1 - if corners[j][not x_dir] > corners[i][not x_dir]: + if corners[j][y_dir] > corners[i][y_dir]: sign = 1 # Find intersections with keepouts intersects = [] - if x_dir: - for k in keepouts: - if abs(start[1] - k[0][1]) < k[1][1]/2: - intersects.append(k) - intersects.sort(key=lambda k: abs(start[0] - k[0][0])) - else: - for k in keepouts: - if abs(start[0] - k[0][0]) < k[1][0]/2: - intersects.append(k) - intersects.sort(key=lambda k: abs(start[1] - k[0][1])) + for k in keepouts: + if abs(start[not y_dir] - k[0][not y_dir]) < k[1][not y_dir]/2: + intersects.append(k) + intersects.sort(key=lambda k: abs(start[y_dir] - k[0][y_dir])) print("Start: ", start) print("end: ", corners[j]) - print("Flag: ", x_dir) + print("Flag: ", y_dir) print("intersects: ", intersects) - for intersect in intersects: - if x_dir: - end[0] = intersect[0][0] - sign * intersect[1][0]/2 - else: - end[1] = intersect[0][1] - sign * intersect[1][1]/2 + if len(intersects): + intersect = intersects[0] + skip_flag = abs(start[y_dir]) < abs(intersect[0][y_dir] - sign * intersect[1][y_dir]/2) + + for intersect in intersects: + end[y_dir] = intersect[0][y_dir] - sign * intersect[1][y_dir]/2 + # if y_dir: + # end[0] = intersect[0][0] - sign * intersect[1][0]/2 + # else: + # end[1] = intersect[0][1] - sign * intersect[1][1]/2 - print("Silk: ", start, end) - kicad_mod.append(Line(start=start, end=end, layer='F.SilkS', width=0.1)) - if x_dir: - start[0] = intersect[0][0] + sign * intersect[1][0]/2 - else: - start[1] = intersect[0][1] + sign * intersect[1][1]/2 + if not skip_flag: + print("Silk: ", start, end) + kicad_mod.append(Line(start=start, end=end, layer='F.SilkS', width=0.1)) + skip_flag = False + start[y_dir] = intersect[0][y_dir] + sign * intersect[1][y_dir]/2 + # if y_dir: + # start[0] = intersect[0][0] + sign * intersect[1][0]/2 + # else: + # start[1] = intersect[0][1] + sign * intersect[1][1]/2 - kicad_mod.append(Line(start=start, end=corners[j], layer='F.SilkS', width=0.1)) + if abs(start[y_dir]) < (corners[j][y_dir]): + print("End Fake: ", start, end) + print("End: ", start, corners[j]) + kicad_mod.append(Line(start=start, end=corners[j], layer='F.SilkS', width=0.1)) # kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.SilkS', width=0.15)) From cf8dce6165960c9ba9a523cfa384045a8f094425 Mon Sep 17 00:00:00 2001 From: ac Date: Sat, 16 Mar 2024 15:46:48 +1000 Subject: [PATCH 067/139] Foot gen: fixed corners logic --- .scripts/foot_gen.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index 23d7911..330da61 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -380,6 +380,7 @@ for i in range(len(corners)): if len(intersects): intersect = intersects[0] skip_flag = abs(start[y_dir]) < abs(intersect[0][y_dir] - sign * intersect[1][y_dir]/2) + print("Skip params: ", abs(start[y_dir]), abs(intersect[0][y_dir] - sign * intersect[1][y_dir]/2)) for intersect in intersects: end[y_dir] = intersect[0][y_dir] - sign * intersect[1][y_dir]/2 @@ -398,7 +399,8 @@ for i in range(len(corners)): # else: # start[1] = intersect[0][1] + sign * intersect[1][1]/2 - if abs(start[y_dir]) < (corners[j][y_dir]): + print("End params: ", abs(start[y_dir]), abs(corners[j][y_dir])) + if abs(start[y_dir]) <= abs(corners[j][y_dir]): print("End Fake: ", start, end) print("End: ", start, corners[j]) kicad_mod.append(Line(start=start, end=corners[j], layer='F.SilkS', width=0.1)) From 3303d59629b2b24e45524974376a65d7ceb8ab21 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 2 Apr 2024 13:05:17 +1000 Subject: [PATCH 068/139] Changed board ID to be 6 digit instead of 4. --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index ae3e6d9..bd92fe2 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -55,7 +55,7 @@ image: do dir=$(dirname $f) echo $dir - if [[ "$dir" =~ ^.?\/?[0-9]{4}-.*$ || "$dir" =~ .+_panel ]] + if [[ "$dir" =~ ^.?\/?[0-9]{6}-.*$ || "$dir" =~ .+_panel ]] then FILT_FILES=$(echo "$FILT_FILES $f") FILT_DIRS=$(echo "$FILT_DIRS $dir") From 39254fcb3391cd9624b0450e875de9746f565a4d Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 15 Apr 2024 13:24:44 +1000 Subject: [PATCH 069/139] Added datsheet field to BOM output --- default.kibot.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/default.kibot.yaml b/default.kibot.yaml index b4ed2ed..14622cf 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -64,6 +64,8 @@ outputs: name: qty - field: Footprint name: footprint + - field: Datasheet + name: datasheet - mpn - manf - field: References From 34a07084f6b35645a6d62718b8ce5a411e75e433 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 15 Apr 2024 21:56:44 +1000 Subject: [PATCH 070/139] Attempting to fix upload job curl install --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index bd92fe2..f52c513 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -243,7 +243,7 @@ upload_job: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch script: - !reference [.commands, strip_tag] - - apt-get update && apt-get -y install zip curl + - apt-get update && apt-get -y -t bookworm-backports install zip curl - | zip -r Fabrication/All.zip Fabrication/ for d in $(find Fabrication/* -maxdepth 0 -type d) From 852964dce09d13943c06a7709ba1bbf8eabf39d2 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 16 Apr 2024 08:47:35 +1000 Subject: [PATCH 071/139] Release job now links to latest packages --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index f52c513..c80d3dd 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -281,7 +281,7 @@ release_job: - | echo "running release_job for $TAG" echo "#!/bin/sh" >> fab.sh - packid=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages | jq .[0].id) + packid=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages | jq .[-1].id) echo "release-cli create --name \"Release $TAG\" --tag-name \"$TAG\" \\" >> fab.sh cnt=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/$packid/package_files | jq length) ids=$(curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/$packid/package_files | jq .[].id) From 75f950fe113e81fa76badf688406c412d4388495 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 16 Apr 2024 11:36:22 +1000 Subject: [PATCH 072/139] Stop lib merging for now, as it isn't working as intended --- kibot-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index c80d3dd..10726a2 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -228,7 +228,6 @@ outputs_all: - !reference [.commands, panel] - !reference [.commands, kibot] - !reference [.commands, neo] - - !reference [.commands, merge_libs] - ls Fabrication/ From 77baad305a24d68a480d0580cdac9e78ca4848f4 Mon Sep 17 00:00:00 2001 From: timmyhadwen Date: Sat, 1 Jun 2024 11:16:43 +1000 Subject: [PATCH 073/139] Updated image for KiCad8 --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 10726a2..d829f05 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -19,7 +19,7 @@ stages: - release image: - name: ghcr.io/inti-cmnb/kicad7_auto:1.6.4 + name: ghcr.io/inti-cmnb/kicad8_auto:1.6.4 .main_rules: rules: From eacc465d8cfac78213c48a589aaff37255ff26f0 Mon Sep 17 00:00:00 2001 From: timmyhadwen Date: Sat, 1 Jun 2024 11:51:01 +1000 Subject: [PATCH 074/139] Updated to 1.6.5 --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index d829f05..04bbd02 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -19,7 +19,7 @@ stages: - release image: - name: ghcr.io/inti-cmnb/kicad8_auto:1.6.4 + name: ghcr.io/inti-cmnb/kicad8_auto:1.6.5 .main_rules: rules: From d326456efe031e488c8385254ca8e176d15f76e1 Mon Sep 17 00:00:00 2001 From: timmyhadwen Date: Mon, 3 Jun 2024 15:02:44 +1000 Subject: [PATCH 075/139] Removed bookworm backports as it was for old image --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 04bbd02..8c356ad 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -242,7 +242,7 @@ upload_job: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch script: - !reference [.commands, strip_tag] - - apt-get update && apt-get -y -t bookworm-backports install zip curl + - apt-get update && apt-get -y install zip curl - | zip -r Fabrication/All.zip Fabrication/ for d in $(find Fabrication/* -maxdepth 0 -type d) From 7c63818110de773731ea3d14ead1f9f6ca4be621 Mon Sep 17 00:00:00 2001 From: timmyhadwen Date: Fri, 26 Jul 2024 18:22:32 +1000 Subject: [PATCH 076/139] Added ignore for libfootprint: --- micromelon_default/micromelon_default.kicad_pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micromelon_default/micromelon_default.kicad_pro b/micromelon_default/micromelon_default.kicad_pro index fd03554..c927e63 100644 --- a/micromelon_default/micromelon_default.kicad_pro +++ b/micromelon_default/micromelon_default.kicad_pro @@ -75,7 +75,7 @@ "items_not_allowed": "error", "length_out_of_range": "error", "lib_footprint_issues": "warning", - "lib_footprint_mismatch": "warning", + "lib_footprint_mismatch": "ignore", "malformed_courtyard": "error", "microvia_drill_out_of_range": "error", "missing_courtyard": "ignore", From c8d6d0abff9cab65fab36c4d4743a5c066b24bbd Mon Sep 17 00:00:00 2001 From: Tim Hadwen Date: Fri, 26 Jul 2024 08:41:25 +0000 Subject: [PATCH 077/139] Revert "Added ignore for libfootprint:" This reverts commit 7c63818110de773731ea3d14ead1f9f6ca4be621 --- micromelon_default/micromelon_default.kicad_pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/micromelon_default/micromelon_default.kicad_pro b/micromelon_default/micromelon_default.kicad_pro index c927e63..fd03554 100644 --- a/micromelon_default/micromelon_default.kicad_pro +++ b/micromelon_default/micromelon_default.kicad_pro @@ -75,7 +75,7 @@ "items_not_allowed": "error", "length_out_of_range": "error", "lib_footprint_issues": "warning", - "lib_footprint_mismatch": "ignore", + "lib_footprint_mismatch": "warning", "malformed_courtyard": "error", "microvia_drill_out_of_range": "error", "missing_courtyard": "ignore", From 19003424bdf2ee177b7b1091f6bdbbca1c925aa3 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 8 Aug 2024 15:39:27 +1000 Subject: [PATCH 078/139] Added script to rotate a pnp file --- .scripts/rot_pick.py | 69 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100755 .scripts/rot_pick.py diff --git a/.scripts/rot_pick.py b/.scripts/rot_pick.py new file mode 100755 index 0000000..e0c6805 --- /dev/null +++ b/.scripts/rot_pick.py @@ -0,0 +1,69 @@ +import csv +import sys +import math +import ast + +if len(sys.argv) != 4: + print("Invalid num args:", len(sys.argv),", should be 4") + exit(1) + +file = sys.argv[1] +rot_deg = float(sys.argv[2]) +dims = [float(i) for i in ast.literal_eval(sys.argv[3])] + +corrected_rows = [] +with open(file,'r', newline='') as csvfile: + spamreader = csv.reader(csvfile, delimiter=',', + quotechar='|', quoting=csv.QUOTE_MINIMAL) + # Read until the header row + for row in spamreader: + corrected_rows.append(row) + # Header row + # Designator,Comment,Footprint,Mid X(mm),Mid Y(mm) ,Rotation,Head ,FeederNo,Mount Speed(%),Pick Height(mm),Place Height(mm),Mode,Skip + if "Designator" in row: + break; + + # Now the remaining rows should all be placement items + # e.g + # U2,AH1806-W,SC-59,220.50,11.10,-0.00,0,53,50,0.0,0.0,1,0 + for row in spamreader: + # Skip empty rows + if len(row) < 10: + continue + # To rotate we need to change cols: 3,4,5 (x,y,rot) + # Easisest way is to conver to polar + x = float(row[3]) + y = float(row[4]) + print("Before: ", x,y) + # rot = float(row[5]) + + r = (x**2 + y**2)**0.5 + theta = math.atan(y/x) + + # Add the rot + rot_rad = math.pi * rot_deg/180 + theta += rot_rad + + # Convert back to cartesian + x = r * math.cos(theta) + y = r * math.sin(theta) + + # Shift x so that the origin can be maintained + x += math.sin(rot_rad) * dims[1] + + print("After: ", x,y) + + # Add the rotation to the component rotation + comp_rot = float(row[5]) + rot_deg + + row[3] = str(x) + row[4] = str(y) + row[5] = str(comp_rot) + + corrected_rows.append(row) + +with open(file.split('.csv')[0] + '_rot' + '.csv','w', newline='') as csvfile: + spamwriter = csv.writer(csvfile, delimiter=',', + quotechar='|', quoting=csv.QUOTE_MINIMAL) + for row in corrected_rows: + spamwriter.writerow(row) From 80765e324ff50cb01bfb3cf57795e36d3814a976 Mon Sep 17 00:00:00 2001 From: ac Date: Mon, 9 Sep 2024 09:31:49 +1000 Subject: [PATCH 079/139] Added user layers to jlc gerbers --- default.kibot.yaml | 72 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 14622cf..4b05c5f 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -2,9 +2,6 @@ kibot: version: 1 -import: - - file: JLCPCB - preflight: run_erc: true update_xml: true @@ -146,14 +143,69 @@ outputs: only_different: true pcb: false old: KIBOT_TAG-0 - - - name: 'JLCPCB_compress' - type: compress - extends: _JLCPCB_compress - options: - output: '%f_JLC.%x' - + - name: JLCPCB_gerbers + comment: Gerbers compatible with JLCPCB + type: gerber + dir: JLCPCB + options: &gerber_options + exclude_edge_layer: true + exclude_pads_from_silkscreen: true + plot_sheet_reference: false + plot_footprint_refs: true + plot_footprint_values: false + force_plot_invisible_refs_vals: false + tent_vias: true + use_protel_extensions: true + create_gerber_job_file: false + disable_aperture_macros: true + gerber_precision: 4.6 + use_gerber_x2_attributes: false + use_gerber_net_attributes: false + line_width: 0.1 + subtract_mask_from_silk: true + inner_extension_pattern: '.g%n' + layers: + # Note: a more generic approach is to use 'copper' but then the filenames + # are slightly different. + - F.Cu + - B.Cu + - In1.Cu + - In2.Cu + - In3.Cu + - In4.Cu + - In5.Cu + - In6.Cu + - F.SilkS + - B.SilkS + - F.Mask + - B.Mask + - Edge.Cuts + - user + + - name: JLCPCB_drill + comment: Drill files compatible with JLCPCB + type: excellon + dir: JLCPCB + options: + pth_and_npth_single_file: false + pth_id: '-PTH' + npth_id: '-NPTH' + metric_units: true + map: gerber + route_mode_for_oval_holes: false + output: "%f%i.%x" + + - name: 'JLCPCB_compress' + comment: ZIP file for JLCPCB + type: compress + options: + files: + - from_output: JLCPCB_gerbers + dest: / + - from_output: JLCPCB_drill + dest: / + output: '%f_JLC.%x' groups: - name: pcb outputs: From fe9a4eb1e2d212d6accf5b321124881f41ede1ac Mon Sep 17 00:00:00 2001 From: ac Date: Mon, 9 Sep 2024 10:11:33 +1000 Subject: [PATCH 080/139] Added default panel files (vscore) to the templates, and made the rotation maths in the neoden pnp file generation more robust --- .scripts/neo.py | 4 +- README.md | 43 ++++++++++--------- .../micromelon_default_panel.json | 38 ++++++++++++++++ tcs_default/tcs_default_panel.json | 38 ++++++++++++++++ 4 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 micromelon_default/micromelon_default_panel.json create mode 100644 tcs_default/tcs_default_panel.json diff --git a/.scripts/neo.py b/.scripts/neo.py index 9bedceb..6084630 100644 --- a/.scripts/neo.py +++ b/.scripts/neo.py @@ -115,8 +115,8 @@ def comp_format(filt, offset): t[p] = "{:.2f}".format(abs(float(t[p]) - offset[n])) rotation = float(t[rot]) rotation = rotation + offset[2] - if rotation > 180.0: - rotation = -1 * (360.0 - rotation) + # Wrap the phase [-180, 180] + rotation = (rotation + 180.0) % (2 * 180.0) - 180.0 t[rot] = "{:.2f}".format(rotation) out.append(t) return out diff --git a/README.md b/README.md index c624881..08269ef 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,43 @@ # Dependencies -- [Kicad 6](https://www.kicad.org/) +- [Kicad 8](https://www.kicad.org/) - [git-lfs](https://git-lfs.com/) +- [kimelon](https://gitlab.com/Micromelon/education/hardware/kimelon) # Setup -1. Fork or clone and change origin remote-url. -2. Checkout dev (branch off dev if desired) -2. Rename/move files to match project name (make sure to update for [CI](#CI) too) +1. From an empty directory: `kimelon config --init --remote `; if git is already setup and pointing to the remote then drop `--remote` +2. Create a kicad project, based off of a template found in this directory 3. Lock the file you want to edit, see [Locking](#Locking) -4. Start editing. +4. Start editing +# Updating +`kimelon config` # Locking All kicad files are read-only by default, the file will need to be locked to your ssh key/gitlab account for it to be writable. -This can be done using `lock.sh {file name}`. -Once you are done editing the lock can be released using `unlock.sh {file name}`. - -Lock/unlock can only be done if there are any branches that aren't merged into `dev` (excluding `main`). +This can be done using `kimelon lock `. +See `kimelon lock --help` for more info. +Once you are done editing the lock can be released using `kimelon unlock `. +See `kimelon unlock --help` for more info. +Lock/unlock can't be done if there are any branches apart from `dev` & `main`. # CI -Edit lines 41 & 42 of .gitlab-ci.yml to match the naming/structure of your project/s. -You can add as many kicad projects as you like, as below: -``` - - DIR: 'proj1' - SCHEM: 'proj1.kicad_sch' - - DIR: 'proj2' - SCHEM: 'proj3.kicad_sch' - - DIR: 'proj3' - SCHEM: 'proj3.kicad_sch' -``` The following will be produced on any commit to dev & main branches or any commit on branch that has an active MR with said branches: - DRC & ERC - Step files - The following will be produced only on commits to main or commits on dev if it has an active MR with main: - JLCPCB compatible gerbers - PDFs of Schematic & PCB - BOM - Currently there are some ERC errors to do with buses (https://gitlab.com/kicad/code/kicad/-/issues/13285), so the docker image used for CI will be run on an older version to avoid them. +# Panels +[Kikit](https://github.com/yaqwsx/KiKit) is used to generate panels by placing a `json` file in your kicad project root folder. + +The templates in this repository all contain a default panel file with the following features: +- single board +- full frame, no tabs/gap between PCB and frame, vcuts +- Mounting hole + fiducial in each corner + +See examples of panel types/options [here](https://yaqwsx.github.io/KiKit/v1.3/panelization/examples/) +See syntax of `json` file [here](https://yaqwsx.github.io/KiKit/v1.3/panelization/cli/) diff --git a/micromelon_default/micromelon_default_panel.json b/micromelon_default/micromelon_default_panel.json new file mode 100644 index 0000000..77f03b7 --- /dev/null +++ b/micromelon_default/micromelon_default_panel.json @@ -0,0 +1,38 @@ +{ + // There can be C-like comments + "layout": { + "type": "grid", + "rotation": 0, + "rows": 1, + "cols": 1 + }, + "tabs": { + "type": "full" + }, + "cuts": { + "type": "vcuts", + "layer" : "Dwgs.User" + }, + "framing": { + "type": "tightframe", + "width": "8mm" + }, + "tooling": { + "type": "4hole", + "hoffset": "2.5mm", + "voffset": "4mm", + "size": "1.65mm" + }, + "fiducials": { + "type": "4fid", + "hoffset": "7mm", + "voffset": "4mm", + "coppersize": "2mm", + "opening": "4mm" + + }, + "post": { + "origin": "bl", + "millradius": "1mm" + } +} diff --git a/tcs_default/tcs_default_panel.json b/tcs_default/tcs_default_panel.json new file mode 100644 index 0000000..77f03b7 --- /dev/null +++ b/tcs_default/tcs_default_panel.json @@ -0,0 +1,38 @@ +{ + // There can be C-like comments + "layout": { + "type": "grid", + "rotation": 0, + "rows": 1, + "cols": 1 + }, + "tabs": { + "type": "full" + }, + "cuts": { + "type": "vcuts", + "layer" : "Dwgs.User" + }, + "framing": { + "type": "tightframe", + "width": "8mm" + }, + "tooling": { + "type": "4hole", + "hoffset": "2.5mm", + "voffset": "4mm", + "size": "1.65mm" + }, + "fiducials": { + "type": "4fid", + "hoffset": "7mm", + "voffset": "4mm", + "coppersize": "2mm", + "opening": "4mm" + + }, + "post": { + "origin": "bl", + "millradius": "1mm" + } +} From 9d7ea27a945578686b0818a7ea565b8966029fa5 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 1 Oct 2024 14:03:49 +1000 Subject: [PATCH 081/139] Added revision field to bom export --- default.kibot.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/default.kibot.yaml b/default.kibot.yaml index 4b05c5f..75b8e20 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -65,6 +65,7 @@ outputs: name: datasheet - mpn - manf + - rev - field: References name: refs exclude_filter: "" From 6e23ebcc3ae52012ca122c5c1e501f19dbe10894 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 1 Oct 2024 15:00:34 +1000 Subject: [PATCH 082/139] Added kintree cli fork as a submodule. Added 'inventree' stage to CI, which runs ki-ntree cli on all the boms it can find in the artifacts dir --- .gitmodules | 4 ++++ .scripts/ki-ntree | 1 + kibot-ci.yml | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 160000 .scripts/ki-ntree diff --git a/.gitmodules b/.gitmodules index 02916e8..61ed493 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,7 @@ path = kicad-footprint-generator url = git@gitlab.com:acmelon/kicad-footprint-generator.git branch = offset_fix +[submodule ".scripts/ki-ntree"] + path = .scripts/ki-ntree + url = https://github.com/Andrew-Collins/Ki-nTree + branch = cli diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree new file mode 160000 index 0000000..316a11d --- /dev/null +++ b/.scripts/ki-ntree @@ -0,0 +1 @@ +Subproject commit 316a11d0da0ca59095148f38f2c6fe77b4d71948 diff --git a/kibot-ci.yml b/kibot-ci.yml index 8c356ad..57686d4 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -15,6 +15,7 @@ variables: stages: - gen_mech - gen_fab + - inventree - upload - release @@ -33,6 +34,8 @@ image: - if: $CI_COMMIT_BRANCH == "dev" .commands: + get_tag: + - TAG=$(echo ${CI_COMMIT_MESSAGE} | tr -d \\n) get_files: - FILES=$(find . -name *$SEARCH -not -path "./.gitlab/*") get_dirs: @@ -124,12 +127,29 @@ image: python3 $CI_PROJECT_DIR/.gitlab/.scripts/neo.py $d done + boms: + - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ + - poetry install + - cd $CI_PROJECT_DIR/Fabrication + - 'SEARCH="bom.csv"' + - !reference [.commands, get_tag] + - !reference [.commands, get_files] + - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ + - | + for f in $FILES + do + echo $f + name=$(echo $f | cut -d'-' -f1)A + poetry run python -m kintree_cli -p $f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings_inv $KINTREE_SETT_INV --settings_ipn $KINTREE_SETT_IPN + done + + git_tag: + - !reference [.commands, get_tag] - | if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then - TAG=$(echo ${CI_COMMIT_MESSAGE} | tr -d \\n) echo "running git tag" - git tag $CI_COMMIT_MESSAGE + git tag $TAG elif [[ $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" && "$CI_MERGE_REQUEST_TITLE" =~ [^a-zA-Z0-9.-_] ]]; then exit 1 fi @@ -230,6 +250,17 @@ outputs_all: - !reference [.commands, neo] - ls Fabrication/ +inventree_job: + stage: inventree + needs: + - job: outputs_all + artifacts: true + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + script: + - !reference [.commands, boms] upload_job: stage: upload From 72625988d1b74aa5848b0cce0a1e96e2a58b0441 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 1 Oct 2024 19:06:20 +1000 Subject: [PATCH 083/139] Cleanup tag functions --- kibot-ci.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 57686d4..afe3e55 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -34,8 +34,6 @@ image: - if: $CI_COMMIT_BRANCH == "dev" .commands: - get_tag: - - TAG=$(echo ${CI_COMMIT_MESSAGE} | tr -d \\n) get_files: - FILES=$(find . -name *$SEARCH -not -path "./.gitlab/*") get_dirs: @@ -132,7 +130,7 @@ image: - poetry install - cd $CI_PROJECT_DIR/Fabrication - 'SEARCH="bom.csv"' - - !reference [.commands, get_tag] + - !reference [.commands, strip_tag] - !reference [.commands, get_files] - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - | @@ -145,7 +143,7 @@ image: git_tag: - - !reference [.commands, get_tag] + - !reference [.commands, strip_tag] - | if [[ $GITLAB_CI == 'true' && $CI_COMMIT_BRANCH == "main" ]]; then echo "running git tag" From 79442489b792752b0e8c22c9b4eda692ce930d24 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 1 Oct 2024 19:29:22 +1000 Subject: [PATCH 084/139] Install poetry --- kibot-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index afe3e55..2e523ba 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -127,6 +127,7 @@ image: boms: - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ + - pip install poetry - poetry install - cd $CI_PROJECT_DIR/Fabrication - 'SEARCH="bom.csv"' From f64c9685baab83cf6416a6e749b899884b73dc39 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 1 Oct 2024 19:44:03 +1000 Subject: [PATCH 085/139] Install pip --- kibot-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 2e523ba..5b467f0 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -127,7 +127,7 @@ image: boms: - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - - pip install poetry + - apt update && apt install pip -y && pip install --break-system-packages poetry - poetry install - cd $CI_PROJECT_DIR/Fabrication - 'SEARCH="bom.csv"' @@ -226,6 +226,7 @@ outputs_dev: SUFF_SCH: run_drc print_sch SUFF_PCB: run_erc,update_xml,set_text_variables print_pcb script: + - !reference [.commands, boms] - !reference [.commands, git_tag] - SUFFIX=$SUFF_SCH - !reference [.commands, kibot] From 2130e95fcf93da74c42a6bef2f43a09c29e9a30b Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 2 Oct 2024 10:08:23 +1000 Subject: [PATCH 086/139] Updated kintree vars to work with CI --- .gitmodules | 2 +- .scripts/ki-ntree | 2 +- kibot-ci.yml | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index 61ed493..a2d914a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,4 +5,4 @@ [submodule ".scripts/ki-ntree"] path = .scripts/ki-ntree url = https://github.com/Andrew-Collins/Ki-nTree - branch = cli + branch = cli diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 316a11d..8d79d0b 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 316a11d0da0ca59095148f38f2c6fe77b4d71948 +Subproject commit 8d79d0b318a1f9a441d3963aa396cb68d7541be6 diff --git a/kibot-ci.yml b/kibot-ci.yml index 5b467f0..6b67a2d 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -129,6 +129,7 @@ image: - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - apt update && apt install pip -y && pip install --break-system-packages poetry - poetry install + - ls - cd $CI_PROJECT_DIR/Fabrication - 'SEARCH="bom.csv"' - !reference [.commands, strip_tag] @@ -138,8 +139,8 @@ image: for f in $FILES do echo $f - name=$(echo $f | cut -d'-' -f1)A - poetry run python -m kintree_cli -p $f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings_inv $KINTREE_SETT_INV --settings_ipn $KINTREE_SETT_IPN + name=$(echo $f | cut -c3- | cut -d'-' -f1)A + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token $KINTREE_DIGI_TOKEN done From 90088a2af2ad0d4038a957c813777fdd9d1be423 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 2 Oct 2024 10:14:55 +1000 Subject: [PATCH 087/139] Disable boms in dev job --- kibot-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 6b67a2d..04c151f 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -227,7 +227,6 @@ outputs_dev: SUFF_SCH: run_drc print_sch SUFF_PCB: run_erc,update_xml,set_text_variables print_pcb script: - - !reference [.commands, boms] - !reference [.commands, git_tag] - SUFFIX=$SUFF_SCH - !reference [.commands, kibot] From d37fd830cf5e828a16e5f858975c70e2b81e2c3e Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 2 Oct 2024 10:36:54 +1000 Subject: [PATCH 088/139] Updated kintree submodule --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 8d79d0b..dd32b59 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 8d79d0b318a1f9a441d3963aa396cb68d7541be6 +Subproject commit dd32b59e0b574a497443341c46439dee0026757b From bef9b5027157109b146e05d88adc6d9a787bc2b3 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 2 Oct 2024 11:20:28 +1000 Subject: [PATCH 089/139] inventree job fail now takes down upload and release, export conn_mpn+conn_manf fields to bom --- default.kibot.yaml | 2 ++ kibot-ci.yml | 1 + 2 files changed, 3 insertions(+) diff --git a/default.kibot.yaml b/default.kibot.yaml index 75b8e20..153d67c 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -66,6 +66,8 @@ outputs: - mpn - manf - rev + - conn_manf + - conn_mpn - field: References name: refs exclude_filter: "" diff --git a/kibot-ci.yml b/kibot-ci.yml index 04c151f..15b2cc4 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -265,6 +265,7 @@ inventree_job: upload_job: stage: upload needs: + - job: inventree_job - job: outputs_all artifacts: true rules: From 6bd6d5f42d90a780e8e5dd0b749c25adcfd88a81 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 3 Oct 2024 16:00:13 +1000 Subject: [PATCH 090/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index dd32b59..f80caf5 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit dd32b59e0b574a497443341c46439dee0026757b +Subproject commit f80caf584ee05d58b9b72e199f8d2b5071385fe4 From d47cef1b70454c726b7c541d76f61e40a6ac4881 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 3 Oct 2024 16:46:04 +1000 Subject: [PATCH 091/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index f80caf5..2cdab90 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit f80caf584ee05d58b9b72e199f8d2b5071385fe4 +Subproject commit 2cdab9032df1d7a7083b7b5015b6e37f3f90a09f From 25c5b4eaf344326a6dd8b24fe4738cfba5abc69a Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 3 Oct 2024 17:21:48 +1000 Subject: [PATCH 092/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 2cdab90..f514aca 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 2cdab9032df1d7a7083b7b5015b6e37f3f90a09f +Subproject commit f514aca07c314c471a8f43e7ea526fbf8f93d36b From adf63a67e02a2694b624c9502c53cadc2a397f57 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 3 Oct 2024 18:02:23 +1000 Subject: [PATCH 093/139] UPdated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index f514aca..bebdba0 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit f514aca07c314c471a8f43e7ea526fbf8f93d36b +Subproject commit bebdba04aa8ef1d4567739fa2383135385d26b9b From ba09a90c5319710414e89ea59bb0555d1df5ffbf Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 8 Oct 2024 10:04:16 +1000 Subject: [PATCH 094/139] Store and retrieving token written, upload tested. --- kibot-ci.yml | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 15b2cc4..0a3b9e3 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -127,22 +127,31 @@ image: boms: - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - - apt update && apt install pip -y && pip install --break-system-packages poetry + - apt update && apt install curl wget pip -y && pip install --break-system-packages poetry - poetry install + - cd /tmp + - url="https://gitlab.com/api/v4/projects/${DIGI_API_PRJ_ID}/packages/generic/digikey_api/0/token_storage.json" + - | + if [[ -z "$KINTREE_DIGI_TOKEN" ]]; then + wget $url + else + cp $KINTREE_DIGI_TOKEN token_storage.json + fi - ls - cd $CI_PROJECT_DIR/Fabrication - 'SEARCH="bom.csv"' - - !reference [.commands, strip_tag] - - !reference [.commands, get_files] + - !reference [.commands, strip_tag] + - !reference [.commands, get_files] - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - | - for f in $FILES - do - echo $f - name=$(echo $f | cut -c3- | cut -d'-' -f1)A - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token $KINTREE_DIGI_TOKEN - done - + for f in $FILES + do + echo $f + name=$(echo $f | cut -c3- | cut -d'-' -f1)A + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token storage_token.json + done + - | + curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file /tmp/token_storage.json $url git_tag: - !reference [.commands, strip_tag] From 7fa4a486db1c4ea5dc4664399853c35553fec9ee Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 8 Oct 2024 11:34:09 +1000 Subject: [PATCH 095/139] Fixed up token download --- kibot-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 0a3b9e3..2abc305 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -127,15 +127,15 @@ image: boms: - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - - apt update && apt install curl wget pip -y && pip install --break-system-packages poetry + - apt update && apt install curl pip -y && pip install --break-system-packages poetry - poetry install - cd /tmp - url="https://gitlab.com/api/v4/projects/${DIGI_API_PRJ_ID}/packages/generic/digikey_api/0/token_storage.json" - | if [[ -z "$KINTREE_DIGI_TOKEN" ]]; then - wget $url + curl --header "JOB-TOKEN: $CI_JOB_TOKEN" $url >> token_storage.json else - cp $KINTREE_DIGI_TOKEN token_storage.json + cp $KINTREE_DIGI_TOKEN token_storage.json fi - ls - cd $CI_PROJECT_DIR/Fabrication From cc258bdb23875178b8ae47b5b49816427b19c86f Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 8 Oct 2024 13:00:31 +1000 Subject: [PATCH 096/139] Fixed up token file name in command --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 2abc305..62d686f 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -148,7 +148,7 @@ image: do echo $f name=$(echo $f | cut -c3- | cut -d'-' -f1)A - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token storage_token.json + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token token_storage.json done - | curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file /tmp/token_storage.json $url From 85aac86cebf52baa9bedb3f0f8e095aa29246ab0 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 8 Oct 2024 13:19:12 +1000 Subject: [PATCH 097/139] Fix up path to token in command --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 62d686f..5ab3b09 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -148,7 +148,7 @@ image: do echo $f name=$(echo $f | cut -c3- | cut -d'-' -f1)A - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token token_storage.json + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token /tmp/token_storage.json done - | curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file /tmp/token_storage.json $url From c64e02af88159a44260862c0eae62ab8e3914c5a Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 8 Oct 2024 13:52:25 +1000 Subject: [PATCH 098/139] Fix up path of token again --- kibot-ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 5ab3b09..9101793 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -129,7 +129,6 @@ image: - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - apt update && apt install curl pip -y && pip install --break-system-packages poetry - poetry install - - cd /tmp - url="https://gitlab.com/api/v4/projects/${DIGI_API_PRJ_ID}/packages/generic/digikey_api/0/token_storage.json" - | if [[ -z "$KINTREE_DIGI_TOKEN" ]]; then @@ -148,7 +147,7 @@ image: do echo $f name=$(echo $f | cut -c3- | cut -d'-' -f1)A - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token /tmp/token_storage.json + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token token_storage.json done - | curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file /tmp/token_storage.json $url From 386b781a8c647e31e4b83e7d1a49748394e20bf7 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 9 Oct 2024 08:56:09 +1000 Subject: [PATCH 099/139] Print out token, shouldn't make a difference but it seems to be working now? --- kibot-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 9101793..b853589 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -136,7 +136,7 @@ image: else cp $KINTREE_DIGI_TOKEN token_storage.json fi - - ls + - cat token_storage.json - cd $CI_PROJECT_DIR/Fabrication - 'SEARCH="bom.csv"' - !reference [.commands, strip_tag] @@ -150,6 +150,7 @@ image: poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token token_storage.json done - | + cat /tmp/token_storage.json curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file /tmp/token_storage.json $url git_tag: @@ -257,6 +258,7 @@ outputs_all: - !reference [.commands, kibot] - !reference [.commands, neo] - ls Fabrication/ + - !reference [.commands, boms] inventree_job: stage: inventree From 0195a7caeadc8961f1f6702cc56dd70cccf87f9f Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 9 Oct 2024 09:03:56 +1000 Subject: [PATCH 100/139] Remove boms job from outputs_all --- kibot-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index b853589..c06cb4e 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -258,7 +258,6 @@ outputs_all: - !reference [.commands, kibot] - !reference [.commands, neo] - ls Fabrication/ - - !reference [.commands, boms] inventree_job: stage: inventree From 9711dce2ef62de0ccbe7cc70b5e7a7303b93fedc Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 15 Oct 2024 09:59:34 +1000 Subject: [PATCH 101/139] Hopefully fix up when inventree_job runs --- kibot-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index c06cb4e..72376bf 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -265,9 +265,7 @@ inventree_job: - job: outputs_all artifacts: true rules: - - if: $CI_COMMIT_TAG - when: never # Do not run this job when a tag is created manually - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + - !reference [.main_rules, rules] script: - !reference [.commands, boms] From 0794509a6b3d8f163641af70108ba35be7a7703a Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 23 Oct 2024 11:20:19 +1000 Subject: [PATCH 102/139] Fixed up inventree_job rules and updated to latest version of ki-ntree cli --- .scripts/ki-ntree | 2 +- kibot-ci.yml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index bebdba0..a8ece2c 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit bebdba04aa8ef1d4567739fa2383135385d26b9b +Subproject commit a8ece2c014db17b01c51a5865bb3742cdae64216 diff --git a/kibot-ci.yml b/kibot-ci.yml index 72376bf..c06cb4e 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -265,7 +265,9 @@ inventree_job: - job: outputs_all artifacts: true rules: - - !reference [.main_rules, rules] + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch script: - !reference [.commands, boms] From e7e6c0b98e3179fc6c5cf32e289fc5369f552f41 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 23 Oct 2024 13:26:29 +1000 Subject: [PATCH 103/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index a8ece2c..18e5cbc 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit a8ece2c014db17b01c51a5865bb3742cdae64216 +Subproject commit 18e5cbcd1b3c1dc336e84dd65ab8540e3ae2cd18 From a85fb9265facd9cf859d0b3e0494b208fda56c9d Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 24 Oct 2024 10:24:36 +1000 Subject: [PATCH 104/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 18e5cbc..0f850d1 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 18e5cbcd1b3c1dc336e84dd65ab8540e3ae2cd18 +Subproject commit 0f850d1838e1ec15e77426cf18927755ebcb1e6b From f7a611c685797b88e43abc80f754c1ac4598a9e6 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 24 Oct 2024 13:27:11 +1000 Subject: [PATCH 105/139] Update ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 0f850d1..e1feeee 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 0f850d1838e1ec15e77426cf18927755ebcb1e6b +Subproject commit e1feeeeea7838ccbcf2df72ae9d14678afee1f60 From 55e7b874ae453e021076a5eef9e86981cb18b380 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 24 Oct 2024 14:14:02 +1000 Subject: [PATCH 106/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index e1feeee..fbbed8a 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit e1feeeeea7838ccbcf2df72ae9d14678afee1f60 +Subproject commit fbbed8ab43dfc9bae2c15dd64c70fbcfaa13f658 From 95129c82060c73cc20200c0b2d51cabc136d6fa6 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 24 Oct 2024 19:07:29 +1000 Subject: [PATCH 107/139] Update ki-ntree and handle failing of ki-ntree commands --- .scripts/ki-ntree | 2 +- kibot-ci.yml | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index fbbed8a..c434eab 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit fbbed8ab43dfc9bae2c15dd64c70fbcfaa13f658 +Subproject commit c434eabe06ec23884f9f14d96643a90d23a500c2 diff --git a/kibot-ci.yml b/kibot-ci.yml index c06cb4e..ca4220f 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -142,16 +142,20 @@ image: - !reference [.commands, strip_tag] - !reference [.commands, get_files] - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ + - FAIL=0 - | for f in $FILES do echo $f name=$(echo $f | cut -c3- | cut -d'-' -f1)A - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token token_storage.json + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 done + # - cp token_storage.json /tmp - | cat /tmp/token_storage.json curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file /tmp/token_storage.json $url + - exit $FAIL + # USE PRIVATE-TOKEN to upload from gitlab-ci git_tag: - !reference [.commands, strip_tag] From 18a7f575e18bcfc7853e63a5ee7b2c89d94e1efc Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 24 Oct 2024 20:25:43 +1000 Subject: [PATCH 108/139] Updated kintree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index c434eab..b2c7baf 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit c434eabe06ec23884f9f14d96643a90d23a500c2 +Subproject commit b2c7bafde46c148fc7592a62efb093320e87fe01 From 086b453119a6a4b188e7a07ae426c3dafdbc45c2 Mon Sep 17 00:00:00 2001 From: ac Date: Fri, 25 Oct 2024 08:46:16 +1000 Subject: [PATCH 109/139] Updated kintree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index b2c7baf..0ee63b8 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit b2c7bafde46c148fc7592a62efb093320e87fe01 +Subproject commit 0ee63b88dad8f18936d6ecf528fd2844c209649a From 1388e1aa20917146a63947725b4f6a7f42b5acc4 Mon Sep 17 00:00:00 2001 From: ac Date: Fri, 25 Oct 2024 09:43:05 +1000 Subject: [PATCH 110/139] Update to latest version of kibot to fix bom items being messed up --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index ca4220f..0f04520 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -20,7 +20,7 @@ stages: - release image: - name: ghcr.io/inti-cmnb/kicad8_auto:1.6.5 + name: ghcr.io/inti-cmnb/kicad8_auto:1.8.1 .main_rules: rules: From cc2f1a760568c9c057ef95c21d0fb86ffe7b12d5 Mon Sep 17 00:00:00 2001 From: ac Date: Fri, 25 Oct 2024 10:06:23 +1000 Subject: [PATCH 111/139] Fixup curl install issue with new kibot image --- kibot-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index 0f04520..e0ebec9 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -127,6 +127,7 @@ image: boms: - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ + - apt remove libcurl4 -y - apt update && apt install curl pip -y && pip install --break-system-packages poetry - poetry install - url="https://gitlab.com/api/v4/projects/${DIGI_API_PRJ_ID}/packages/generic/digikey_api/0/token_storage.json" From 5b02ae0d089f8d3da3bb94de1c4842215f735a31 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 25 Oct 2024 11:51:42 +1000 Subject: [PATCH 112/139] Updated kintree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 0ee63b8..7f588de 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 0ee63b88dad8f18936d6ecf528fd2844c209649a +Subproject commit 7f588de36e50da00e3069b0bbf5dcb6e39d9663f From f9ec76c65acdf4f00e072c2f7c651592e916e427 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 25 Oct 2024 13:41:50 +1000 Subject: [PATCH 113/139] Do the curl trick in the upload job too --- kibot-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/kibot-ci.yml b/kibot-ci.yml index e0ebec9..44f1411 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -288,6 +288,7 @@ upload_job: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch script: - !reference [.commands, strip_tag] + - apt remove libcurl4 -y - apt-get update && apt-get -y install zip curl - | zip -r Fabrication/All.zip Fabrication/ From 658d0c19aabde8754a0bce5c9b60472deb0f0cce Mon Sep 17 00:00:00 2001 From: ac Date: Tue, 29 Oct 2024 08:47:26 +1000 Subject: [PATCH 114/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 7f588de..a21dfaa 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 7f588de36e50da00e3069b0bbf5dcb6e39d9663f +Subproject commit a21dfaac3b0cf1760ade1e4f197615339501ada1 From 72cdc871a3291f3b9ff0a8ac62da41cccbbfbfce Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 30 Oct 2024 16:47:49 +1000 Subject: [PATCH 115/139] Added render of bland and populated pcb --- .scripts/ki-ntree | 2 +- default.kibot.yaml | 26 ++++++++++++++++++++++++++ kibot-ci.yml | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index a21dfaa..bebdba0 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit a21dfaac3b0cf1760ade1e4f197615339501ada1 +Subproject commit bebdba04aa8ef1d4567739fa2383135385d26b9b diff --git a/default.kibot.yaml b/default.kibot.yaml index 153d67c..7b74d6d 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -113,6 +113,32 @@ outputs: download: false subst_models: true + - name: 'pcb_render' + comment: "ISO render of the blank PCB" + type: render_3d + dir: . + options: + view: 'top' + rotate_z: 45 + rotate_y: 35 + download: false + download_lcsc: false + output: 'PCB_%f_%r.%x' + show_components: 'none' + + - name: 'pcba_render' + comment: "ISO render of the assembled PCB" + type: render_3d + dir: . + options: + view: 'top' + rotate_z: 45 + rotate_y: 35 + download: false + download_lcsc: false + output: 'PCBA_%f_%r.%x' + show_components: 'all' + - name: 'neo_position' comment: "Pick and place" type: position diff --git a/kibot-ci.yml b/kibot-ci.yml index 44f1411..aaa4ef0 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -221,7 +221,7 @@ output_mech: paths: - Fabrication/**/* variables: - SUFF_MECH: run_erc,run_drc step + SUFF_MECH: run_erc,run_drc step pcb_render pcba_render script: - !reference [.commands, git_tag] - SUFFIX=$SUFF_MECH From 3307a734fda567bc674705a881882a8bfc02b7d9 Mon Sep 17 00:00:00 2001 From: andrewc Date: Wed, 30 Oct 2024 17:24:30 +1000 Subject: [PATCH 116/139] Tuned in the rendering --- default.kibot.yaml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 7b74d6d..24fb39c 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -119,10 +119,12 @@ outputs: dir: . options: view: 'top' - rotate_z: 45 - rotate_y: 35 + rotate_z: 4 + rotate_x: 3 + zoom: -1 download: false download_lcsc: false + orthographic: true output: 'PCB_%f_%r.%x' show_components: 'none' @@ -132,10 +134,12 @@ outputs: dir: . options: view: 'top' - rotate_z: 45 - rotate_y: 35 + rotate_z: 4 + rotate_x: 3 download: false + zoom: -1 download_lcsc: false + orthographic: true output: 'PCBA_%f_%r.%x' show_components: 'all' From 111a9bc0421d4697fd8dd0f3cd53a16b1e39a582 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 31 Oct 2024 11:16:07 +1000 Subject: [PATCH 117/139] Add description to PCB and PCBA parts --- .scripts/ki-ntree | 2 +- kibot-ci.yml | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index bebdba0..404d443 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit bebdba04aa8ef1d4567739fa2383135385d26b9b +Subproject commit 404d44352cc4fcd215db9372b6ffdcf4bc34b7e8 diff --git a/kibot-ci.yml b/kibot-ci.yml index aaa4ef0..fa3a4a5 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -126,6 +126,10 @@ image: done boms: + - ls /gcl-builds/Fabrication/999999-test/ + - client=$(echo $CI_PROJECT_PATH | cut -d'/' -f3 | sed -r 's/\<./\U&/g') + - proj=$(echo $CI_PROJECT_NAME | tr -d '0123456789' | tr '-' ' ' | sed -r 's/\<./\U&/g') + - desc_suffix=$(echo $client $proj) - cd $CI_PROJECT_DIR/.gitlab/.scripts/ki-ntree/ - apt remove libcurl4 -y - apt update && apt install curl pip -y && pip install --break-system-packages poetry @@ -149,7 +153,10 @@ image: do echo $f name=$(echo $f | cut -c3- | cut -d'-' -f1)A - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG'}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 + fab_path=$CI_PROJECT_DIR/Fabrication/$(dirname $f | cut -c3-) + pcb_im=$fab_path/PCB_$(echo $f | cut -c3- | rev | cut -d'/' -f1 | cut -c9- | rev).png + pcba_im=$fab_path/PCBA_$(echo $f | cut -c3- | rev | cut -d'/' -f1 | cut -c9- | rev).png + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG', 'image': ['$pcb_im', '$pcba_im'], 'desc': '$desc_suffix'}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 done # - cp token_storage.json /tmp - | @@ -267,6 +274,8 @@ outputs_all: inventree_job: stage: inventree needs: + - job: output_mech + artifacts: true - job: outputs_all artifacts: true rules: From 7b137bedf57058438ca0f101a2df7185bc1292ac Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 31 Oct 2024 11:21:23 +1000 Subject: [PATCH 118/139] Update ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 404d443..c12e97f 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 404d44352cc4fcd215db9372b6ffdcf4bc34b7e8 +Subproject commit c12e97f9cfabe33a66aae6f6a14087f8d764ad8a From cee186c17cb39b229d0ee39417e9d587108f0794 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 4 Nov 2024 17:22:01 +1000 Subject: [PATCH 119/139] Added attachments to PCB and PCBA parts --- .scripts/ki-ntree | 2 +- default.kibot.yaml | 9 +++++++++ kibot-ci.yml | 9 ++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index c12e97f..c836f1a 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit c12e97f9cfabe33a66aae6f6a14087f8d764ad8a +Subproject commit c836f1ab4d67aaf74e0153fc03157a0ac0f21c5e diff --git a/default.kibot.yaml b/default.kibot.yaml index 24fb39c..00b2310 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -177,6 +177,14 @@ outputs: pcb: false old: KIBOT_TAG-0 + - name: 'interactive_bom' + comment: "Interactive html BOM" + type: ibom + dir: . + options: + output: '%f_%r_%i.%x' + dark_mode: true + - name: JLCPCB_gerbers comment: Gerbers compatible with JLCPCB type: gerber @@ -246,6 +254,7 @@ groups: - neo_position - print_pcb - stencil + - interactive_bom - name: sch outputs: diff --git a/kibot-ci.yml b/kibot-ci.yml index fa3a4a5..a79d5fe 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -154,9 +154,12 @@ image: echo $f name=$(echo $f | cut -c3- | cut -d'-' -f1)A fab_path=$CI_PROJECT_DIR/Fabrication/$(dirname $f | cut -c3-) - pcb_im=$fab_path/PCB_$(echo $f | cut -c3- | rev | cut -d'/' -f1 | cut -c9- | rev).png - pcba_im=$fab_path/PCBA_$(echo $f | cut -c3- | rev | cut -d'/' -f1 | cut -c9- | rev).png - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG', 'image': ['$pcb_im', '$pcba_im'], 'desc': '$desc_suffix'}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 + name_n_rev=$(echo $f | cut -c3- | rev | cut -d'/' -f1 | cut -c9- | rev) + pcb_im=$fab_path/PCB_$name_n_rev.png + pcba_im=$fab_path/PCBA_$name_n_rev.png + pcb_attach=$(echo "['$fab_path/${name_n_rev}_PCB.pdf']") + pcba_attach=$(echo "['$fab_path/${name_n_rev}_schematic.pdf', '$fab_path/${name_n_rev}_bom.csv', '$fab_path/${name_n_rev}-neo-pos_top.csv', '$fab_path/${name_n_rev}-neo-pos_bot.csv', '$fab_path/${name_n_rev}_ibom.html']") + poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG', 'image': ['$pcb_im', '$pcba_im'], 'desc': '$desc_suffix', 'attachments': [$pcb_attach, $pcba_attach]}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 done # - cp token_storage.json /tmp - | From 8e2516d2d0829c814b3f2514d25543825d75a89d Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 18 Nov 2024 11:40:49 +1000 Subject: [PATCH 120/139] Allow for a preceeding letter in partnumber of pcb --- kibot-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index a79d5fe..540055f 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -56,7 +56,7 @@ image: do dir=$(dirname $f) echo $dir - if [[ "$dir" =~ ^.?\/?[0-9]{6}-.*$ || "$dir" =~ .+_panel ]] + if [[ "$dir" =~ ^.?\/?[a-z]?[0-9]{6}-.*$ || "$dir" =~ .+_panel ]] then FILT_FILES=$(echo "$FILT_FILES $f") FILT_DIRS=$(echo "$FILT_DIRS $dir") From 8deba4f856ab2604f6718c5cc86aab4c560ec6e0 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 18 Nov 2024 12:39:22 +1000 Subject: [PATCH 121/139] Remove hardcoded debug line --- kibot-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 540055f..5196bb3 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -126,7 +126,6 @@ image: done boms: - - ls /gcl-builds/Fabrication/999999-test/ - client=$(echo $CI_PROJECT_PATH | cut -d'/' -f3 | sed -r 's/\<./\U&/g') - proj=$(echo $CI_PROJECT_NAME | tr -d '0123456789' | tr '-' ' ' | sed -r 's/\<./\U&/g') - desc_suffix=$(echo $client $proj) From 827bd847145a212749be13e528206bb9bf530471 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 18 Nov 2024 14:01:35 +1000 Subject: [PATCH 122/139] Upload zipped gerbers to inventree PCB part, added revision to jlc zip file name --- default.kibot.yaml | 2 +- kibot-ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 00b2310..23e4af9 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -246,7 +246,7 @@ outputs: dest: / - from_output: JLCPCB_drill dest: / - output: '%f_JLC.%x' + output: '%f_%r_JLC.%x' groups: - name: pcb outputs: diff --git a/kibot-ci.yml b/kibot-ci.yml index 5196bb3..722ec6f 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -156,7 +156,7 @@ image: name_n_rev=$(echo $f | cut -c3- | rev | cut -d'/' -f1 | cut -c9- | rev) pcb_im=$fab_path/PCB_$name_n_rev.png pcba_im=$fab_path/PCBA_$name_n_rev.png - pcb_attach=$(echo "['$fab_path/${name_n_rev}_PCB.pdf']") + pcb_attach=$(echo "['$fab_path/${name_n_rev}_PCB.pdf', '$CI_PROJECT_DIR/Fabrication/${name_n_rev}_JLC.zip']") pcba_attach=$(echo "['$fab_path/${name_n_rev}_schematic.pdf', '$fab_path/${name_n_rev}_bom.csv', '$fab_path/${name_n_rev}-neo-pos_top.csv', '$fab_path/${name_n_rev}-neo-pos_bot.csv', '$fab_path/${name_n_rev}_ibom.html']") poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG', 'image': ['$pcb_im', '$pcba_im'], 'desc': '$desc_suffix', 'attachments': [$pcb_attach, $pcba_attach]}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 done From 76691183e4fe1e65d7b2b070ebf6166bacc25554 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 18 Nov 2024 15:46:09 +1000 Subject: [PATCH 123/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index c836f1a..9b70aa4 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit c836f1ab4d67aaf74e0153fc03157a0ac0f21c5e +Subproject commit 9b70aa43c660c0dda9253d21312caf77c9e4b6f6 From 913f0c356fdb8174797d43c113b86870fd1ad000 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 18 Nov 2024 17:03:01 +1000 Subject: [PATCH 124/139] Update kibot, fixup kibot preflight opttions --- default.kibot.yaml | 5 +- kibot-ci.yml | 2 +- melon.kicad_wks | 874 ++++++++++++++++++++++----------------------- 3 files changed, 425 insertions(+), 456 deletions(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index 23e4af9..df37db6 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -3,9 +3,9 @@ kibot: version: 1 preflight: - run_erc: true + erc: true update_xml: true - run_drc: true + drc: true set_text_variables: - name: 'rev' command: 'if [ $(git describe --tags | wc -w) -gt 0 ]; then git describe --tags | sed -e "s/\([r,R][0-9]\+\)*$//g"; else echo $CI_COMMIT_SHORT_SHA; fi' @@ -19,7 +19,6 @@ preflight: expand_kibot_patterns: true command: 'echo $KIBOT_PCB_NAME | rev | cut -d"/" -f1 | rev | cut -d"." -f1 ' fill_zones: true - ignore_unconnected: false global: environment: diff --git a/kibot-ci.yml b/kibot-ci.yml index 722ec6f..35a4602 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -20,7 +20,7 @@ stages: - release image: - name: ghcr.io/inti-cmnb/kicad8_auto:1.8.1 + name: ghcr.io/inti-cmnb/kicad8_auto:1.8.2 .main_rules: rules: diff --git a/melon.kicad_wks b/melon.kicad_wks index afc5cb7..96a189f 100644 --- a/melon.kicad_wks +++ b/melon.kicad_wks @@ -1,453 +1,423 @@ -(kicad_wks (version 20220228) (generator pl_editor) - (setup (textsize 1.5 1.5)(linewidth 0.15)(textlinewidth 0.15) - (left_margin 10)(right_margin 10)(top_margin 10)(bottom_margin 10)) - (rect (name "") (start 110 34) (end 2 2) (comment "rect around the title block") -) - (rect (name "") (start 0 0 ltcorner) (end 0 0) (repeat 2) (incrx 2) (incry 2)) - (line (name "") (start 50 2 ltcorner) (end 50 0 ltcorner) (repeat 30) (incrx 50)) - (tbtext "1" (name "") (pos 25 1 ltcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50)) - (line (name "") (start 50 2 lbcorner) (end 50 0 lbcorner) (repeat 30) (incrx 50)) - (tbtext "1" (name "") (pos 25 1 lbcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50)) - (line (name "") (start 0 50 ltcorner) (end 2 50 ltcorner) (repeat 30) (incry 50)) - (tbtext "A" (name "") (pos 1 25 ltcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50)) - (line (name "") (start 0 50 rtcorner) (end 2 50 rtcorner) (repeat 30) (incry 50)) - (tbtext "A" (name "") (pos 1 25 rtcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50)) - (tbtext "Date: ${ISSUE_DATE}" (name "") (pos 87 6.9)) - (line (name "") (start 110 5.5) (end 2 5.5)) - (tbtext "${KICAD_VERSION}" (name "") (pos 109 4.1) (comment "Kicad version") -) - (line (name "") (start 110 8.5) (end 2 8.5)) - (tbtext "Rev: ${REVISION}" (name "") (pos 24 6.9) (font bold)) - (tbtext "Size: ${PAPER}" (name "") (pos 109 6.9) (comment "Paper format name") -) - (tbtext "Id: ${#}/${##}" (name "") (pos 24 4.1) (comment "Sheet id") -) - (line (name "") (start 110 12.5) (end 2 12.5)) - (tbtext "Title: ${TITLE}" (name "") (pos 109 10.7) (font (size 2 2) bold italic)) - (tbtext "File: ${FILENAME}" (name "") (pos 109 14.3)) - (line (name "") (start 110 18.5) (end 2 18.5)) - (tbtext "Sheet: ${SHEETPATH}" (name "") (pos 109 17)) - (tbtext "Micromelon Robotics" (name "") (pos 109 20) (font bold) (comment "Company name") -) - (tbtext "In association with: ${partner}" (name "") (pos 109 23) (comment "Comment 0") -) - (tbtext "Client: ${client}" (name "") (pos 109 26) (comment "Comment 1") -) - (tbtext "${COMMENT3}" (name "") (pos 109 29) (comment "Comment 2") -) - (tbtext "${COMMENT4}" (name "") (pos 109 32) (comment "Comment 3") -) - (line (name "") (start 90 8.5) (end 90 5.5)) - (line (name "") (start 26 8.5) (end 26 2)) - (bitmap (name "") (pos 28.989 25.3822) (scale 1) - (pngdata - (data "89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 02 38 00 00 00 A1 08 06 00 00 00 CA 83 C5 ") - (data "54 00 00 00 04 73 42 49 54 08 08 08 08 7C 08 64 88 00 00 00 09 70 48 59 73 00 00 2E 18 00 00 2E ") - (data "18 01 2A AA 27 20 00 00 20 00 49 44 41 54 78 9C ED 9D 5D 92 DA D6 F6 F6 9F 25 3E F2 DE B5 4E 55 ") - (data "4B E6 CE 9C 11 98 73 97 6A 27 65 65 04 86 11 98 8C 20 9D 11 18 8F 20 ED 11 04 8F 00 3C 82 D0 75 ") - (data "62 57 EE 42 8F E0 D0 77 0E 72 D5 9F BE 3B 07 90 D6 7B 21 D1 08 1A 49 7B EB 0B BA B3 7E 55 A9 8A ") - (data "1B 21 6D 84 D8 FB D9 EB 13 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 ") - (data "41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 ") - (data "04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 ") - (data "10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 84 ") - (data "53 84 8E 3D 80 C7 02 8F BE 6D AF 51 6F 03 70 00 80 0C DF D9 BE 48 AF 0E BC E5 0E C4 53 00 80 4F ") - (data "0B 06 4D 0D F0 C2 07 4D EB A8 4F A9 37 59 94 3E 68 41 10 04 41 F8 9B 22 02 27 86 E5 E8 A2 43 30 ") - (data "BA 64 F8 0E 98 3A 00 CE 0A BE C4 2D 33 8F 1B BD CF 97 05 9F 57 10 04 41 10 FE F6 88 C0 89 B0 1E ") - (data "7D DF 05 FC 2E 08 5D 14 2F 68 0E E2 33 FF AB D9 FB 3C AD E2 5A 82 20 08 82 F0 77 A1 7E EC 01 1C ") - (data "9B D5 E8 3B 87 C0 FD 40 D4 F8 95 88 9A 28 0D F8 E2 AA 12 04 41 10 84 82 F9 5B 0A 1C 1E 39 A6 87 ") - (data "65 17 44 03 80 9F 1F 71 28 B7 D4 FB 63 76 C4 EB 0B 82 20 08 C2 93 E4 6F 25 70 78 E4 98 6B AC 2F ") - (data "3D 5A 5D 02 54 B9 B5 E6 E1 80 30 39 F6 10 04 41 10 04 E1 29 F2 B7 10 38 51 61 43 F9 63 6B 6E 41 ") - (data "3C 63 DF 98 00 00 C1 9F 31 8C D9 FE 41 04 32 19 DC 31 0C EE 32 E3 45 CC C8 26 39 C7 22 08 82 20 ") - (data "08 C2 01 9E BC C0 59 8F 2E FA 1E AD 06 04 64 73 45 11 5F 87 62 66 D2 E8 FD 3E D1 7C F7 D8 1B BD ") - (data "5C 80 F0 CB A1 17 6B F0 75 CF 27 08 82 20 08 82 02 4F 56 E0 2C 47 17 1D C3 C0 55 4C 8D 9A 24 EE ") - (data "C0 18 03 C6 B8 86 DA 84 BA F9 EA D5 30 D0 89 79 49 E2 6F 04 41 10 04 A1 24 9E A4 C0 59 8D BE 1B ") - (data "10 F1 5B B0 C6 9B 88 AF E1 63 58 EF 7D 1E 16 3A 18 0A 0A 03 3E 40 E2 6F 04 41 10 04 A1 34 9E 94 ") - (data "C0 E1 D1 B7 6D DF A8 8D 99 39 26 E6 E5 01 77 60 8C 6B F0 06 D4 2D DE 9A C2 A3 6F DB 5E AC 6B 4C ") - (data "E2 6F 04 41 10 04 A1 2C 9E 8C C0 09 62 6D E8 0A AC 14 44 7C C7 4C 57 75 D4 AF CA 6C 99 E0 C1 70 ") - (data "E2 5E 93 F8 1B 41 10 04 41 28 8F 27 21 70 56 A3 8B 2B 10 FD A4 74 30 E3 43 0D 8D CB 6A 7A 41 91 ") - (data "13 F3 82 C4 DF 08 82 20 08 42 89 3C 6A 81 C3 23 C7 F4 8C E5 58 29 90 98 F8 DA F7 71 59 69 5B 04 ") - (data "89 BF 11 04 41 10 84 A3 F0 68 05 4E 10 6F B3 1A 83 29 2D DE E6 8E 18 83 5A F7 F3 55 25 03 0B 09 ") - (data "AA 25 AF 24 FE 46 10 04 41 10 8E C0 A3 14 38 CB D1 45 C7 23 9A A4 C5 DB 10 E1 C6 F0 BD EE 31 DC ") - (data "41 1E 96 DD B8 5E A6 12 7F 23 08 82 20 08 E5 F2 E8 04 CE 72 74 D1 31 88 26 48 A9 48 CC CC EF EB ") - (data "DD CF 97 D5 8C EA C0 F5 81 4E 4C AB 76 89 BF 11 04 41 10 84 92 79 54 02 47 51 DC DC 81 8D 7E A3 ") - (data "F7 EF 71 45 C3 3A 88 61 90 C3 87 EA F0 48 FC 8D 20 08 82 20 94 CE A3 11 38 8A E2 E6 D6 67 EE 36 ") - (data "7B FF AE 2E 90 F8 00 3C 72 4C 8F 57 D2 7F 4A 10 04 41 10 8E C4 A3 10 38 2A E2 26 88 B7 69 38 F5 ") - (data "4A D2 BF 93 F1 E0 39 71 AF 49 FC 8D 20 08 82 20 94 8F 71 EC 01 A4 C1 23 C7 AC 19 34 84 82 B8 A9 ") - (data "A6 B6 4D 3A 1C 2F 70 24 FE 46 10 04 41 10 2A E0 E4 05 8E 6F AC 26 CC 88 4D 05 3F 35 71 03 04 F1 ") - (data "37 07 5F 90 F8 1B 41 10 04 41 A8 84 93 16 38 EB D1 CB E1 63 13 37 3C 72 CC F8 31 4B FC 8D 20 08 ") - (data "82 20 54 C1 C9 0A 1C 6F F4 F2 12 84 37 71 AF 9F A2 B8 01 24 FE 46 10 04 41 10 4E 81 93 14 38 CB ") - (data "D1 45 87 09 BF C4 BD 7E AA E2 06 90 F8 1B 41 10 04 41 38 05 4E 4E E0 F0 C8 31 0D A2 A4 1A 36 77 ") - (data "9E CF FD BC E2 86 47 DF B6 BD D1 CB C2 0B 01 4A FC 8D 20 08 82 20 1C 9F 93 13 38 1E 56 43 00 31 ") - (data "3D 9C 00 66 EA E6 6D 98 19 B4 7A A8 FD 87 09 BF 78 1F 5F 4E 79 E4 98 79 CE 77 3F 36 89 BF 11 04 ") - (data "41 10 84 93 E0 A4 04 CE 7A F4 7D 17 84 D7 71 AF 13 E3 E7 46 EF F7 49 DE EB 34 D0 9C 6D FE 9F 19 ") - (data "2F 7C 63 35 29 42 E4 48 FC 8D 20 08 82 20 9C 06 27 23 70 78 E4 98 20 7F 18 7F 00 3E D6 7A 9F 0A ") - (data "E9 08 4E BD C9 02 C4 D7 F7 A7 0E 45 4E DE F3 4A FC 8D 20 08 82 20 9C 06 27 23 70 3C AC AE 10 5F ") - (data "CC EF AE 86 46 BF C8 EB B1 6F 0C 76 FE CD 78 B1 1A 5D E4 12 50 12 7F 23 08 82 20 08 A7 41 4C C3 ") - (data "EB 6A 59 8D BE 73 88 F8 B7 B8 D7 99 E9 87 22 5C 53 FB AC 3F 5E 4C C0 F4 6A F7 62 46 AF 9E A1 51 ") - (data "27 8F 1C D3 A3 D5 FF 1D 7E 91 7F AC F7 3E 0F 33 0D 52 38 2A 96 65 75 98 6B 26 C0 1D C3 E0 07 6E ") - (data "4C DF 37 26 00 B0 5E FF 77 BA 58 2C 4E 2E AB EF 94 D9 DC 5B C3 F0 9D B8 63 98 79 C6 5C 9B 7D FD ") - (data "FA 65 52 DD C8 04 21 1B 96 65 75 88 A8 0D A0 03 00 CC BB 9B 5E 66 5E 18 06 A6 BE 4F 0B 80 A6 32 ") - (data "6F 94 CB 49 08 1C EF E3 CB 69 5C 70 2E 33 BF 6F F4 3E 17 9E ED 04 C4 0A AB DB 1A 37 3A BA 59 5A ") - (data "41 FC 90 3F 3A F4 5A 8D BD 7F AA B8 A8 2C CB EA 87 3F 0E 65 0C C3 18 7E F9 F2 25 F5 DC 0A D7 EE ") - (data "10 51 57 F5 78 DF 47 87 88 4C D7 FD CB 49 3A CE B6 ED 2E 33 95 F2 FD 45 46 33 75 5D B7 90 6B 6C ") - (data "EE 43 30 31 F1 AB D4 37 EC 72 07 D0 94 88 27 BE 6F 4C B2 2C CA E7 E7 CF 2E 89 A0 FC 3D 24 C3 33 ") - (data "22 CC C2 7F 4C 99 79 E6 BA EE D1 1A D1 B6 5A AD F6 7A CD DD E0 F3 69 DF 5B 00 B8 21 C2 B8 A8 67 ") - (data "7E 9F 2C F7 9E 88 AF E6 F3 B9 F6 86 68 9F 56 AB D5 F6 3C 1E EA BE AF 56 A3 BE CA BD A8 E6 77 78 ") - (data "18 66 8C BF 7E FD 2B D1 3A 6E DB F6 60 5F 0C C4 41 C4 93 F9 7C 3E 28 62 6C 79 31 4D D3 6C 34 1A ") - (data "5D 66 EA 12 C1 41 72 33 E8 38 6E 98 69 58 AF D3 B8 8C E7 DA B2 9E 4D F4 DE 91 6F 3E B5 2C AB 0F ") - (data "18 FD F4 23 79 E6 BA 73 85 E3 B2 73 F4 66 9B EB D1 45 3F A1 5A F1 5D 1D CD 41 59 D7 6E F4 7E 9F ") - (data "AC 46 17 EF 89 E8 A7 C8 9F 9F AF B1 BE 04 A0 75 5D 86 E7 D0 61 BD A8 11 7F 43 57 CC 7A 3F 10 CF ") - (data "F3 66 00 86 3A EF 89 B9 76 62 D5 E8 07 47 13 00 F0 4D DA 71 CC EC 00 C8 B2 98 29 43 41 23 D6 CC ") - (data "98 A6 69 36 9B CD 4B DF 47 1F C0 73 66 00 E0 2C A7 3A 03 F8 15 33 5E 11 F9 6F 2D CB BE 03 30 06 ") - (data "F8 4A 55 58 10 71 1F 50 FF 1E 52 78 C5 3B 1F 83 60 59 F6 1D 33 26 44 3C 76 5D 77 58 D0 75 12 D9 ") - (data "4C 78 9E E7 BF A2 7C 5B AA 17 CC 78 E1 79 FE 5B CB 7A 76 CD 4C 83 22 2D 3B 59 84 17 33 4F 01 E4 ") - (data "16 38 81 B8 D1 17 D4 5F BE FC 35 53 39 90 39 B3 A8 CC 0D 51 BA 70 0B C7 A7 F4 DC FB 7E 62 19 91 ") - (data "4A 38 3F 6F 39 44 7E 1F 08 8A D1 E6 7D AE 89 F8 17 CF E3 5F 2C CB FE 50 AB 19 83 A2 84 CE F9 79 ") - (data "CB 01 7C CD EF 9D 5E B5 5A AD AB EC 63 30 FA 8A CF 5A C6 F3 AB 73 FC 18 1C A2 41 EC 6B CC 97 65 ") - (data "17 F3 AB A3 39 20 C2 CE 42 4D C4 97 BA 59 55 79 E3 6F 5A AD 56 1B 99 D4 BF DA AE 27 09 DB B6 07 ") - (data "C8 B6 A8 2A 2C DA F9 C7 97 C6 C6 4D A4 4B AB D5 6A 5B 96 3D 6C 34 9A FF C7 8C B7 44 F1 E5 09 32 ") - (data "72 06 E0 0D 40 7F 5A D6 B3 49 30 D9 C4 63 9A A6 89 E2 C4 4D EC 98 88 F0 1A A0 5F 2D CB 5E D8 B6 ") - (data "3D 08 AF 5B 38 96 65 F5 CF CF ED 19 40 BF 16 BF B8 F2 2B 22 FF 37 CB B2 AE 8A 1B 7F 96 31 1A 9D ") - (data "BC 57 3D 3F 7F 76 99 ED DA A4 63 8D CB 3D CE 1C 24 8E 53 FF B9 D7 FA DC 85 62 59 56 C7 B2 9E 4D ") - (data "88 FC DF 80 F8 4A FB 39 78 E3 79 FE 34 78 26 F2 93 E4 FE 4D C2 F3 BC 1C D7 57 7B 96 99 CB FF 1E ") - (data "8F 2A 70 D6 A3 8B 3E E2 6A DE 10 5F 57 11 B7 42 BD C9 C2 F0 BD 2E 80 BB C8 9F CF 7C AC FA AA E7 ") - (data "28 A2 FE 8D E7 C5 A7 98 A7 90 6B E2 0A E2 20 F0 36 DB BB 93 3F 5B 45 0B 36 D6 EB FF 6A FF 50 6C ") - (data "DB 1E 78 9E 3F 45 39 93 D4 01 F8 15 90 90 25 08 A0 5E FF 7F 55 2F 42 67 CC 78 5B AF 37 A7 96 65 ") - (data "15 76 ED 60 11 B0 A7 00 FD 5A 82 68 DC 83 7E 6A 34 9A 93 BC E3 4F 13 9F F1 E4 13 6E 81 4B 94 63 ") - (data "AB B6 27 41 A4 36 B7 54 F5 3B 8C E1 2E CD 7A D9 6C 36 1D 9D 13 1E 23 1E CB 34 4D D3 B2 AC 2B 80 ") - (data "FE AC C0 12 76 46 C4 BF 58 96 3D CC 7B 22 DF CF BA 3E 50 3F CB C6 41 E7 77 48 54 7E E9 94 E3 5A ") - (data "70 12 AC 37 FB 59 4E A5 0E A3 F7 C7 CC 0F 5C 29 F7 22 87 0D 56 F6 C5 17 54 FF 26 EB 04 FD 22 EB ") - (data "0E 36 78 1F 0D 33 5E 17 B5 5A 6D 92 F4 7A 45 0B F6 8D 4E 90 5E 68 B5 99 86 A2 2E 8B BF 3C 33 44 ") - (data "C9 D6 BC AC BB AD BC 04 22 84 72 8B 04 60 63 0D A4 3F 51 ED 82 FA 22 EF F8 F3 DC FB EC E2 08 C8 ") - (data "F3 FB 53 B5 5C EA 0A 88 22 61 35 0B B6 C6 F7 46 D7 E9 C7 14 8B 65 59 9D 7A BD 39 05 76 42 19 AA ") - (data "E0 4D 5E 91 13 C6 05 65 E1 AC 5E FF A6 AF FB 26 66 43 F5 7A A9 C2 B7 08 8E 26 70 12 AD 37 8C 0F ") - (data "65 64 4D 25 D1 EC 7D 9E 86 22 E7 36 18 03 29 FF E8 8A A9 7F 93 DD 95 93 55 48 34 1A 8D 01 B2 2F ") - (data "44 77 69 3E DA 6A 16 6C F5 0A D1 B6 6D 77 43 AB CD 91 76 B3 C9 63 55 0D B2 2C 89 33 66 1A E7 11 ") - (data "CB E7 E7 F6 38 BB 35 30 37 B9 C6 9F 7D A7 0B 00 9C E9 BD 39 5C C3 00 B4 2C 19 47 73 4F 19 46 BA ") - (data "1B 5B E7 B9 57 B5 5A 15 45 10 3F 46 7F 96 6F 89 8C 25 B3 C8 09 05 7F 8E 4D 1C 67 70 53 B1 A3 76 ") - (data "5C 35 6E C6 E3 59 70 12 AC 37 35 78 B1 AF 95 49 B3 F7 79 5A E3 46 87 99 DF 87 62 47 89 BC F1 37 ") - (data "79 4D C8 59 84 44 B0 EB CC BE 23 51 D9 99 55 B4 60 2B FD 50 2C CB EA 33 63 84 8A AD 36 51 D2 2C ") - (data "5E C7 0A 02 DD 40 84 E7 CD 66 53 7B 52 0B 32 49 9A 13 4A A8 42 5E 05 44 78 5E AF 37 87 19 DF EB ") - (data "64 BF B2 FA 5C B1 21 9F 6B 18 00 90 1A E0 BF E1 98 C2 59 CD CA A4 F5 DC 57 16 7F 13 8A 9B 5F AB ") - (data "BA 5E 02 6F 6C DB CE 92 59 99 4B D8 12 E1 79 86 EB 2A 5D B3 2A A1 7A 94 2C AA F5 E8 FB 2E E0 C7 ") - (data "5A 6F 8E 59 F5 37 0C 6A 56 9E E4 79 E4 98 1E AF 72 C5 DF 04 16 18 5F F5 92 0F D0 DD 7D 06 82 2A ") - (data "39 1E 24 1D 95 CC A5 6C 3B 5B 1D D2 45 C3 C9 4C 54 89 16 AF 22 63 60 F2 C0 0C AD 0C C2 8D B8 41 ") - (data "46 81 CE 8C 5B 00 D3 E8 4E 3F 63 8A 3E 00 80 08 AF 6D DB EE EA A4 6E E7 DF E9 66 59 48 B2 BB A6 ") - (data "02 74 16 88 E3 09 E7 34 2B 53 98 E5 A3 7C BE E5 72 99 78 BE A2 C8 39 67 DC 31 63 B2 AD 77 03 18 ") - (data "06 9B 41 69 8D 6C 9B 00 DF C7 95 69 9A 13 BD 9A 39 F9 85 6D 58 5A 40 E9 B7 14 94 3A 88 59 D7 F7 ") - (data "C8 9A 18 A2 CB 91 D2 C4 FD 7E DC 2B C7 B2 DE 64 A5 88 F8 1B C3 F0 9D DD 74 5E 3D 74 77 9F A1 6B ") - (data "2A A7 C9 35 DD C4 C8 6C 74 89 BC C5 BE AF 35 4C B1 8C 2D EC B8 8F EB CE 33 27 61 86 13 68 A6 89 ") - (data "8A 19 B7 44 3C 66 AE 8D 0F 4D D4 C1 B9 B9 A3 92 DA 9D 66 F1 62 36 1C 22 B5 87 80 19 B7 86 11 5F ") - (data "1A 80 99 CD B0 2E 47 96 EF F8 EC FC BC E5 A8 BA 3F 1A 8D 6F C6 AA E9 BD 7B 7C 00 F8 EA EB D7 C3 ") - (data "7E F8 4D EA 7E 28 B8 B4 C4 87 EF E3 0A 7A A9 DB B9 77 BA AD 56 AB AD 9A 56 1B D4 7C C9 E7 26 55 ") - (data "2D 8D A0 2B 20 88 F0 2E E3 90 1E C0 CC 33 85 A3 74 EE BD 56 BC 5D 56 B2 CE 19 E1 7C 31 48 2A BF ") - (data "10 8A 80 01 34 93 1B 02 EB E4 37 7D 00 CA D5 F6 99 E1 E4 4C 5F 07 C0 AF 54 9F ED 20 51 46 ED 82 ") - (data "59 12 43 B2 50 B9 C0 E1 D1 B7 6D 2F 4E C5 12 5F 53 37 BF F5 66 35 FA 6E 40 86 EF B0 8F 29 60 8C ") - (data "CB 8C E7 29 A2 FE 4D B8 63 CD 33 8C 33 D5 87 30 FC F1 E6 0E 96 53 59 00 E3 8E D1 13 74 D9 83 0A ") - (data "C3 C9 44 BF 2A 75 38 51 7D FD 9A 5C 27 26 FC 7C 13 00 57 A1 68 BB 42 AC D0 49 5B 90 D4 DD 1C 44 ") - (data "3C 9E CF DD 41 CA 61 97 E1 98 C6 D0 B6 4E 70 07 48 77 41 06 59 25 BA 75 63 70 0B 18 FD B4 E7 27 ") - (data "5C C8 06 96 65 8D C3 7B A7 FC 19 88 F0 5C 47 A4 15 B1 D3 F5 7D BF 03 85 BA 1E 05 B8 A6 00 00 86 ") - (data "61 28 2E 10 7A 02 A2 FA 02 7A 5A EE BD D2 17 C5 AC 73 06 11 DE B9 6E FA BD 0B E7 E8 BE 65 59 13 ") - (data "7D 0B 11 5F 42 51 E0 98 A6 69 16 15 37 14 0A B2 BE C2 A1 AA CF 5A 25 42 15 38 42 0C CE 1A F5 7E ") - (data "DC 6B 45 65 4E 11 F1 5B 30 BD 22 A2 9F 88 F8 B7 F5 F8 E5 6C 35 FA 6E C0 A3 6F DB 45 9C 3F 4A 31 ") - (data "FD A7 F2 9B 90 55 D2 CC 8B 71 4D 01 79 33 19 AA 0A 2A 0C 27 2A 5D D7 C3 87 F5 7A D9 D1 2D 82 F7 ") - (data "F5 EB 97 89 EB CE 3B 71 3B 60 85 94 48 9D 85 48 69 A2 0F 16 78 FD F8 90 43 2D 29 F6 C9 18 C3 75 ") - (data "B3 5E 2F 3B 3A 69 BE 81 F5 4F FF 33 10 79 CA B1 03 CC 79 E2 6F EE 51 FC FE F2 BA A6 02 91 A8 5E ") - (data "84 4D E7 DE 55 1B C0 0B E8 5A 9F CB 1F 5F 58 4D 5A 67 CE B8 63 36 7E D0 15 86 C1 FC C2 EF 75 DE ") - (data "43 84 E7 AA AE EC 82 33 E7 DE A8 05 EF AB CE EB D5 3D 67 95 0B 9C D0 9C 7F 88 DB A2 2C 2D CC 0F ") - (data "1E 9C E7 44 FC D6 A3 DA 7F 02 A1 A3 57 C4 2F F6 3A 05 D4 BF 29 30 F6 22 F5 3C 8D 46 63 50 84 AA ") - (data "CF 1F 20 56 7E 50 61 96 0C 15 66 FA D9 75 E7 FD 3C BB 8B F9 7C 3E 60 36 7E C0 6E 5D A5 C4 94 C8 ") - (data "56 AB D5 D6 F9 5E 54 E2 8E 36 04 D7 2D 23 B5 56 5B 28 DF B8 EE BC 93 E5 DE 86 F7 EE 83 CE 7B 98 ") - (data "D5 DA 8E 14 B5 D3 55 11 ED 81 C5 2B 7F 06 5F 5A B9 81 BD 63 1D F5 63 F3 55 04 D7 45 B7 B8 A9 CE ") - (data "73 9F 85 6C 05 17 59 C3 52 B8 CB 6A B5 1A 60 77 9E 48 BF 9A 62 1A 36 6B 24 C9 A8 A0 98 7C A0 FA ") - (data "6C 57 16 28 5E A9 C0 59 8E 2E 3A 88 89 FD 20 56 F7 2D A6 D1 E8 7D BE 04 1F 9E 10 03 A1 B3 9A 05 ") - (data "81 CE F9 28 22 FE 46 A3 6E 40 0A C9 13 6C DE AC A9 3D 32 3F A0 BA 82 2E 4B 50 61 AB D5 6A 87 B1 ") - (data "1B CA 10 E1 5D 5A BF 1C 55 22 96 93 3B 20 3D FE 46 A7 C8 A3 DE EE 3D A0 E8 8C 05 DB B6 75 85 F2 ") - (data "CD 6A B5 74 F2 5C B3 56 D3 B3 EE AA 8E AF B8 9D 6E F2 C2 58 E4 EF 4F B5 02 AC AE 80 50 77 7B 15 ") - (data "83 66 71 D3 D4 B2 14 79 08 84 2E 0F F4 DE C5 3F E6 A9 E5 12 88 7D BD FE 63 44 AA 2E C7 FC 15 B6 ") - (data "A3 84 6D 6C 62 D1 A9 05 55 B6 50 8D 52 A9 C0 A1 04 3F 9E 81 C6 B0 C8 6B D5 7B 9F FA 60 FE 11 87 ") - (data "15 F2 19 C8 1F AD 46 17 B9 16 B4 62 EA DF 14 A6 B4 63 D5 73 71 AE A9 80 3C 99 0C 9A 82 2E 93 AF ") - (data "36 F4 19 2B 4F EC CC F8 58 74 EC C1 C6 B5 12 B8 AC 8C B4 E7 AC 70 F7 54 1E 92 32 1C 4C D3 34 75 ") - (data "C5 23 C0 B9 AC 62 C0 7D EC 82 72 6A 34 A0 36 E9 16 B9 D3 8D 13 EF 45 FF FE 54 2B C0 96 2D 9C 0B ") - (data "40 BD D6 98 96 CB 5F 9F D0 42 A1 35 67 14 D1 CB 8D B9 A6 19 EF 43 6D C5 33 17 9A 39 17 BA C7 FA ") - (data "71 AF AB 96 2A A9 FA 39 AB 56 E0 C4 75 AB 66 7C 2C A3 E7 54 BD F7 79 58 63 AF 03 E2 83 26 7A 22 ") - (data "FA 69 3D 7A 39 CC 7A FE 62 E2 6F 8A 2B C2 15 37 A1 D7 EB CD 61 81 85 AA 72 06 88 95 1B 54 18 EE ") - (data "5A 75 32 14 EE D6 EB 65 5F F7 3A 2A B8 AE 3B 9D CF E7 0A 0D 21 75 82 5C F5 DD 08 BA 75 50 EA F5 ") - (data "F8 60 59 DD 85 20 08 BE 2C AC 62 69 09 E2 4E 6D A7 1B A6 B3 A7 1C 63 38 87 FE 5E 94 6B 38 44 A7 ") - (data "02 AC F2 DC A2 E3 F6 2A 8E 72 9F 7B 55 32 88 F6 C2 E6 0C 7D F7 96 6A 7C 9C 1A 7A 59 73 F1 1D C2 ") - (data "35 E6 98 4A AD 84 95 65 51 25 B9 A7 00 D6 8E 5A 57 25 B4 A4 38 AB D1 77 0E 19 FE 00 4C BB CA 96 ") - (data "F0 66 35 BA 58 34 7A 9F B5 76 A5 45 D4 BF D1 A9 1B 80 20 06 21 65 E1 7E 98 FD 62 DB 76 97 B9 D0 ") - (data "02 6C 79 1F 50 0D 41 A7 EF 5A F1 FD F8 12 04 07 AF C0 34 A8 2A A2 3F 01 8D 2E EE 7A FD 5B C2 67 ") - (data "4C 79 37 97 B6 C3 F2 7D F4 35 52 4F EF 96 CB 65 61 AE 67 22 CC F2 94 53 38 8C F2 4E 77 0A C0 44 ") - (data "82 B8 3B E4 3E 28 2A 6B 31 72 15 8D DF 9F 9E B0 CD D7 72 22 A0 5E C7 4C 65 87 7E 4A 0D 36 1B 8D ") - (data "46 17 7A A2 FD AA E0 39 E3 4E E3 FA A9 F7 4C 23 4B F5 6E B9 5C 5E 35 1A AA 9B 16 7E 15 9F 9D A8 ") - (data "EA 3A AB 36 CE AB 32 81 53 03 39 71 F7 BC 86 66 69 02 67 43 18 C0 1C 08 1D F0 25 22 A9 EA A1 65 ") - (data "49 4B E0 14 11 7F A3 53 37 80 08 63 66 A4 FC 10 D9 41 24 8D 30 DC 99 0C 93 CE BB D9 99 AA EF 30 ") - (data "B3 C7 73 68 0A BA 4C BE 5A 9D 9D 18 33 6E 8B 8A BB C9 8A 6E 9D 12 5D 6B C8 7A ED 5F E9 D5 C2 A0 ") - (data "D8 FB 11 8A 65 E5 EF AF 84 85 A0 50 F4 EE 3D 4D 00 98 49 82 68 3F 1B 4B D1 35 75 87 20 BD 5C 69 ") - (data "B1 2F B1 C1 E6 1B 22 3F 77 E3 59 DF C7 3B 28 14 8A D4 2D 6E 5A 6E 83 4D D2 9A FB 8B 14 ED E1 F5 ") - (data "A7 45 BA 94 C2 82 82 A9 30 63 B2 58 2C 16 96 65 0D 55 E3 C3 88 FC 3E F6 36 D1 3A 85 32 AB 68 B0 ") - (data "19 A5 32 17 55 6C F3 CA 92 DC 53 71 34 7A BF 4F EA BD 4F DD 7A F7 13 31 D3 0F 60 FE B1 C6 FA 9D ") - (data "BC 8B 89 BF 51 B7 66 04 71 2F A9 BB 98 9D F3 85 65 EB 13 1F 3C C3 C0 65 59 19 3C FB 94 1D 54 18 ") - (data "96 15 D7 48 F1 8C 5F CC AB 42 AF CD 86 7A 36 54 D0 FD D8 1E 6A 56 4E BD 5B AF FF 37 8C 7B 31 14 ") - (data "D8 CA 18 86 11 7B AE 53 40 E7 DE 13 F9 93 34 71 41 84 E7 D1 74 5A 15 D7 14 11 FA 00 DA AA E3 50 ") - (data "AD 00 7B 84 CE F4 00 D4 C7 57 D6 73 AF 4B E8 D2 D6 11 82 1F 8E 2C DA 53 B3 AE D4 33 E7 02 6B 4A ") - (data "AD 56 D3 99 07 DF 84 F7 EC 1E 9D B8 CA 2A 1A 6C 46 A9 2E 06 67 DF 35 14 42 0A 05 C5 CA 22 10 3B ") - (data "9F 87 59 5A 43 14 13 7F A3 66 42 66 C6 ED 62 B1 58 A8 4C B0 9B 87 CF B6 ED 6E DA E2 C6 8C 8F 8A ") - (data "03 DD 90 37 93 A1 D4 A0 42 DD 05 B8 5E A7 D2 2D 87 69 14 5D 13 28 10 36 56 3F E8 7E AC 5D 2D 35 ") - (data "2D 18 58 E7 FE DE 1C 21 68 55 0B 9D 16 27 E1 C4 9C 3A 39 6F 84 85 4A D6 14 33 3E 86 D5 7E 95 45 ") - (data "B9 6A 05 D8 63 75 A6 57 B5 B4 9C 4A 83 CD F5 3A 66 E3 1D 03 91 56 85 6C 45 D2 E3 6A 22 23 48 FC ") - (data "FE F5 DA 8E 04 E7 FA F2 E5 CB 4C 67 2D D8 0F 03 50 CF EC AA BE 13 7C 25 2E AA D5 E8 3B 27 AE 52 ") - (data "AF 77 84 E2 52 79 29 22 FE 46 C7 84 1C 09 00 4C 9D DC 7C DF EF 98 A6 B9 48 73 4D 21 0C 94 D3 69 ") - (data "AE 98 3F 93 A1 EC 60 5A AD D2 E4 27 B2 00 AB 57 9A 65 46 3B AC EF 73 F0 B5 20 C3 22 30 75 67 28 ") - (data "D1 FE 21 A9 7F 93 6E BF 26 E6 FC 05 ED CA 46 63 A7 7B 0D 6C 5A 0F 24 DF 58 C3 F0 1D D3 34 A7 2A ") - (data "AE A9 7A DD B8 5C AF B9 AB DA A2 03 1A 01 FE 05 54 47 CF 82 46 96 DB A9 34 D8 D4 CB A2 D3 E9 71 ") - (data "A6 41 EE DA 48 11 94 E7 93 A8 18 35 0C 0C 55 63 35 F7 FB D5 A9 CE BB 55 77 82 07 AA 8B C1 71 62 ") - (data "FE 7E DB EC 7D AE D4 64 55 04 45 C4 DF E8 F9 A0 83 07 C3 30 8C A9 E7 25 BF 87 99 9D 7A BD D9 47 ") - (data "CA 62 B4 D9 AD 5B D6 33 47 7D 22 CC 1E 20 56 76 50 A1 7E C1 B6 E3 0B EB 0C 4D 1E DF 24 07 0F 66 ") - (data "5E D0 3E B8 EE BC 9F 78 66 8D 5E 59 01 C5 07 85 32 B3 A9 1A B3 06 24 5B 13 F4 E2 06 82 67 C5 75 ") - (data "DD A9 65 D9 29 63 24 A7 5E 6F 76 D2 9E 45 66 1A 7C F9 F2 65 66 59 76 49 41 F7 C7 68 B0 59 4E 71 ") - (data "D3 32 1B 6C EA 55 52 AE DE 02 F1 10 3F E5 77 A5 BA 89 DC FD 2C F3 F9 7C 7C 7E 6E DF 2A CE A1 67 ") - (data "96 65 F5 5D D7 1D 9E 62 83 CD 28 95 B8 A8 28 CE 5C CA D5 A6 8C 15 45 42 FC CD 9D AA BB 4B D3 84 ") - (data "7C 6F 4A 44 AA 0F 96 FA 2A AE A9 ED 4E 44 67 22 CC BE 68 E9 C6 04 E8 06 15 EA 9E BF EA AA AD 87 ") - (data "28 AE C8 63 1E F8 7D 9A B8 01 74 CC D0 01 E5 04 85 6A 15 2F 4B 8B 55 50 3E D7 EE C4 9C B6 C8 B1 ") - (data "42 C7 68 BA DE 04 B7 6B B6 89 50 FA FD 1D AB 33 BD EA 6F AA 8A 5A 58 2A 84 9B 2E 8D 0D 46 9A B8 ") - (data "D0 47 37 73 8D 88 D2 EE 85 D2 77 7F D8 9A A2 1E 93 C8 4C 03 E0 BE 07 9B 12 55 35 D8 8C 52 4D 0C ") - (data "0E D3 C1 9B 70 CC F8 9B 3C 14 11 7F A3 E1 83 DE AB 7B 91 2A 32 D2 7E B0 F7 35 1C 74 7F 5C 79 16 ") - (data "AD B2 83 0A 75 63 0E 7C DF 38 7A 76 8F AE 68 28 98 3B 22 F4 5C D7 55 74 51 52 5B F5 C4 2A 35 63 ") - (data "B2 A1 73 BF D2 7E 27 EA EE D2 DD 89 39 75 91 4B FD FD D5 6A D4 07 CA 6B D1 71 2C E1 AC D1 00 D4 ") - (data "D1 38 6D 69 8B 62 86 4D 51 E1 73 06 91 D7 D6 39 3E AD 08 27 72 B4 4B 08 13 0C 94 5A 47 6C 1A DA ") - (data "6A 14 CA AC AC C1 66 94 D2 5D 54 3C FA B6 ED C5 FC E8 FD 02 CC D8 3C 72 CC 35 D6 1D 03 DC 61 18 ") - (data "33 06 2F EA 58 CF B2 04 0E AB 5E 2F 2E FE 46 4F B0 A9 59 4E F6 E3 5E 88 78 C2 8C CC E6 E7 DD 40 ") - (data "52 AD 05 A3 80 06 9B 6A 2E 8E 2A 7C B5 E5 A6 9D AA A1 19 33 54 14 77 44 B8 5A 2E 97 9A 29 DC EA ") - (data "CF 0A 11 CD 32 8C 2B 91 D0 14 AE 51 AB 24 F5 19 52 FD 3C FB 13 73 AE 39 6B E3 9A 02 F4 76 BF E5 ") - (data "35 D8 2C 06 CD 0A B5 25 B9 E5 F4 30 0C DF D4 A9 AB 54 8E 8B 45 AF 56 51 D2 BC D5 6C 36 55 EB DF ") - (data "1C 74 FB 05 21 0B F6 18 CA C9 09 FE 25 60 98 6A F3 FA 71 42 02 4A 17 38 6B D4 DB 14 73 03 8A 68 ") - (data "AE E9 63 D5 27 C2 2F 1C FE 8B 00 78 A8 61 3D 7E 09 10 5F B3 8F 29 60 8C 8B 6A E4 99 14 7F 63 C0 ") - (data "53 0A 40 D3 31 21 1B C6 83 09 35 C7 04 4B D7 F3 F9 5F 91 31 AA 4F 84 A7 DE 60 53 B5 F6 C3 A9 A0 ") - (data "5B 13 A8 00 6E 98 69 B8 5E FF 6F 98 71 27 A5 DB 95 BD 50 82 60 5C F5 E3 99 E3 8B 87 EA ED 74 1F ") - (data "3C F7 B9 7E 7F D1 BA 4B C1 EE 57 F9 43 E9 5C 57 43 8C A2 57 52 E0 EC 41 AA A8 85 A5 C1 31 2D A8 ") - (data "00 74 37 39 A9 9B CC AC A2 FD 9E 5A CD 18 78 9E 5A 3D A4 C0 15 AB AC 10 8F 12 8E 52 85 8B CA 89 ") - (data "F9 7B 21 66 6C 86 31 43 9C 59 8D E9 15 11 FD 44 C4 BF AD C7 2F 17 EB D1 CB 61 90 D1 95 E7 7A F9 ") - (data "E3 6F 74 4C C8 FB BB 86 1C 0D F1 EE 4D E3 1B F4 02 EC 4E BB C1 26 11 69 A4 5A 1E 1F 9D DD 7B 31 ") - (data "F0 D5 D7 AF 7F 9D 74 E1 BD 24 88 B8 AF 71 78 62 3B 03 CD 06 9B 3B E7 C9 53 C7 63 FF F7 A7 17 53 ") - (data "A4 16 DF A2 EB F6 FA 3B 37 D8 3C 36 61 29 0F E5 EF 8A 39 39 45 BD 88 76 09 C1 FD 2E 3E 98 BA CA ") - (data "06 9B 51 2A 10 38 FE E1 85 87 78 56 C4 D9 EB BD 7F 8F 6B EC 75 E2 BA 87 47 38 03 E1 4D 28 76 66 ") - (data "59 85 0E 19 31 2A 59 2B 85 5A DD 72 B2 6F 92 54 0B 34 3E 70 C5 88 69 1C D0 EF 34 7C EA 0D 36 1F ") - (data "1B 45 36 79 54 BB 5E 10 14 F8 18 09 05 B2 4E 2A 6D 9A 45 42 59 58 1C 9E 98 F5 17 00 22 BC 7B B8 ") - (data "58 AB 5B 35 A5 C1 E6 D3 A3 F8 BA 5D AA CF 53 5A 3D 35 56 0E 36 56 BA DA 71 9E 33 00 15 08 9C 38 ") - (data "41 C0 05 FA 33 A9 F7 C7 AC DE FB D4 AF 71 E3 1F C4 F8 39 AE B9 66 84 E7 44 FC DB 7A F4 BD D6 03 ") - (data "06 A0 A8 82 85 39 0B 23 E9 C6 2E ED 9A C6 01 FD 89 F0 94 1B 6C 3E 4E D4 7D EF CC F8 48 84 77 FB ") - (data "FF E9 2C B4 44 78 1E 57 43 E7 F4 D1 2B A5 0F 24 4F D0 AA 3B DD F8 89 59 3B 9B E6 66 BF 5B BD 6E ") - (data "80 BF 34 D8 7C 5A E8 37 05 A6 EB 24 91 A0 F3 3C A5 59 53 E6 F3 F9 B8 E0 44 81 A3 CD E9 95 F5 A2 ") - (data "AA 82 B0 E5 C3 15 80 2B 1E 39 A6 07 CF 61 70 87 0C DF 01 53 1B 7B CD 3E 7D 78 33 9D F3 17 51 B0 ") - (data "50 CF 07 7D 78 22 D5 0C 34 7E E0 9A 0A CF E2 28 BE BF 88 89 F0 24 82 0A A3 C4 37 8D AB 0C 8D 06 ") - (data "9B 3C 98 CF 1F 2E 70 C1 B3 C4 FF 51 3D 0F 33 2E 4D D3 AC C0 4D A5 53 99 35 99 D0 7A A3 53 91 F9 ") - (data "26 5D 0C 68 35 D8 D4 F9 7B DC F5 FA FB 7F D1 68 88 08 3D 8B 91 8E 70 2E AF 81 E5 21 4E A9 C1 66 ") - (data "16 C2 4C CD 49 11 E7 D2 EF 11 97 56 38 52 39 09 40 C9 ED 17 16 FE 7B AB 78 CE 14 8E 27 54 CB 17 ") - (data "38 31 16 0F 94 9C 22 1E 8A 9D 31 F6 CC D5 9B AC AB 8C 41 C7 4E CC DF EF 54 0B 16 EA 35 D8 8C 7D ") - (data "30 94 7F F8 FB AE A9 08 95 88 8E 13 0B 2A BC 47 37 3D 53 15 CB B2 3A CC 35 33 49 3C 15 D5 60 33 ") - (data "28 14 67 BD 57 6D 94 07 E0 AC D1 68 0C A0 D9 58 36 03 2F 4C D3 34 8B 11 52 BA 15 91 93 AD 37 19 ") - (data "1A 6C 1E 42 F9 F7 47 84 77 87 C4 A9 4E 50 7C 59 0D 36 AB 6E 7C 78 5A 0D 36 01 68 0A D5 A0 5A 78 ") - (data "7E C2 A6 B5 CA 3D E2 82 A6 C0 EE 30 E5 28 47 F1 5C 13 95 E3 C2 2E E3 85 08 9C AA 9F B3 28 D5 F5 ") - (data "A2 3A 11 A8 37 59 64 CD A8 4A 28 58 A8 73 3E 65 61 11 17 F7 A2 1E 18 F8 D0 35 05 64 EA 34 9C 79 ") - (data "27 55 55 50 A1 6E 96 17 33 E9 BB 27 53 08 5C 40 F4 27 91 9F B8 C8 16 59 13 68 B5 5A 0D A0 15 93 ") - (data "45 3F ED 37 CB 2B 62 1C FB 34 1A 8D DC F7 37 74 A9 29 3F A7 CC B8 75 DD D4 85 40 C3 85 73 78 62 ") - (data "D6 70 17 3D 70 4D 6D CF AD 1E E0 5F 52 83 CD C4 40 EC 32 38 95 06 9B 1B 32 D4 C2 CA FD 4C B7 5A ") - (data "AD B6 42 1B 9D 1D 88 78 90 7E 8C 5E 83 CD 34 C2 CD 49 5A 5C AB 12 55 3F 67 51 8E 26 70 18 FE E3 ") - (data "0B 24 2D 24 FE 46 AF C1 E6 A1 D7 D4 45 80 7F 70 A7 AE 99 45 92 77 22 AC 24 A8 D0 F7 F5 8A 70 11 ") - (data "E1 75 B6 85 FE 21 AD 56 AB 6D 59 CF 26 5B 93 6E B2 D8 2A B2 D1 60 D0 84 15 5A 41 81 9E E7 0F 74 ") - (data "8E 0F D0 4D 0A 30 FA FA D7 D8 62 59 56 5F DF 44 AE 72 4D F5 78 B0 E4 E7 5E 65 01 3E 9C F9 A5 DB ") - (data "A2 A3 9C 06 9B D5 BB 7F 74 9E FB 32 AA 06 EF 93 C1 42 74 66 59 56 3F EB F5 4C D3 34 3D CF 1F 43 ") - (data "AB E4 02 5D A7 89 76 BD 84 11 9D EF BD 88 60 E3 E3 B6 B7 28 55 E0 F0 C8 89 F5 C5 3F B6 1E 54 49 ") - (data "59 57 9A 0D 43 75 1B 6C C6 1D 91 F8 E0 10 E1 5D C2 04 5D 61 26 43 35 41 85 59 CC A0 9E C7 C3 AC ") - (data "D7 03 82 09 CB B6 ED 81 E7 F9 FF 89 C6 75 A4 97 AC 57 B7 22 A8 EC DE 97 CB E5 15 F4 32 EB DE E8 ") - (data "06 B9 EA BB 29 F9 95 6D DB 99 76 BC C1 22 42 BF 6A 5D 8D F1 51 65 C1 D2 6D B0 19 4F DA 02 CC EF ") - (data "8B F8 FD 41 BB C1 A6 1A C7 68 7C A8 97 35 56 55 DC 86 EE 02 4C 57 A1 05 5C 0B D3 34 CD 46 A3 39 ") - (data "81 76 63 CD C3 9B D4 28 3A 56 72 1D 51 17 3C BF F9 04 CA 71 9E B3 2D A5 C6 E0 AC B1 EE 3C A2 DA ") - (data "6B 69 38 31 7F 57 8E BF D1 F3 FF 27 3F 18 AE FB 57 DC 78 D2 CF AC 51 55 F8 40 A1 41 65 AA 0C 2A ") - (data "74 5D 77 AA D1 2C 2E 84 5F 9D 9F DB E3 F5 7A D9 D7 89 17 31 4D D3 6C 36 9B 97 CC B8 64 7E B8 73 ") - (data "4A 4A A9 2F 63 F7 BE 58 2C 16 B6 6D 5F E9 58 3C 42 B3 B7 A3 7A FC 6A B5 1A 37 1A 4D 5D D1 31 B4 ") - (data "2C CB D1 B1 00 5A 96 75 A5 11 53 B4 B9 CE ED A6 FD 48 12 3A D5 90 D3 26 E6 B0 C5 45 C6 58 26 1D ") - (data "D1 5F 4E 83 CD AA 1B 1F 9E 52 83 CD 5D FC 21 10 1B 27 7A 88 B3 46 A3 39 31 4D D3 51 9D 33 CE CF ") - (data "5B 0E 91 AE E5 06 60 A6 9F BF 7E 9D 2B FC 76 B2 35 D8 54 43 FB FE EC BE FB 08 0D 36 A3 3C A9 2C ") - (data "AA 32 09 33 B1 1E BE A0 61 E1 D0 CB 9C 28 33 B5 AE 9A 89 B0 EA A0 42 22 1E EB 2E 8E 44 78 DD 68 ") - (data "34 67 E7 E7 CF 06 F5 3A 8D E3 DC 7F A1 A8 71 C2 DA 15 DD 43 C2 26 24 71 C7 AD D9 95 5B 79 F7 1E ") - (data "06 05 5E 42 79 12 E5 57 3A 99 64 61 19 F7 0F D0 CB 68 3A 03 E8 4F DB B6 DF C5 C5 A2 6C 08 5C 52 ") - (data "34 00 74 04 2A 00 E0 8E 88 BB 2A F7 49 27 C0 1F 25 FE FE 34 5B 74 28 8D 43 57 40 18 86 EF D8 B6 ") - (data "ED E8 BC 27 0E 66 9E A5 B9 51 74 BB D1 37 1A DF 8C 2D EB 59 DE A1 01 08 EA BA C4 55 6B 0E 85 FB ") - (data "15 F4 C4 C7 8B 7A BD 39 B5 2C 6B 90 F4 B9 03 61 C3 03 C0 CF 22 10 3E 1C 8A 9F 8C 41 E9 BB CF 62 ") - (data "4D 71 5D 77 78 7E 6E 0F F4 36 8E 5B 8E D1 60 33 8A 08 1C 55 0A 88 BF D1 B0 9C 94 16 00 A8 9B C1 ") - (data "93 B6 00 06 EE 84 C3 B1 0F CC 7E 5B 7D 64 B8 B3 AC 67 07 AF 45 C4 93 B4 05 12 00 6A B5 DA 95 E7 ") - (data "F9 5A 02 27 E4 8C 88 7F F1 3C FE 25 B0 02 ED F6 52 62 E6 36 11 9E AB 89 D3 D4 22 5A A5 64 AF 65 ") - (data "B1 E2 84 A9 A7 6D D5 A3 75 CA B8 47 61 C6 5B CB B2 2F 01 8C 89 30 DB 88 E6 50 F0 B7 11 04 6F 9E ") - (data "65 6B B5 C1 97 EA BF 15 75 CB 49 59 16 04 D3 34 CD B2 1A 6C EA 08 88 E2 52 80 01 22 7A A7 70 45 ") - (data "47 EF AC 5A AD 5D 12 F1 7D 63 10 F7 5A B6 DF 4D 50 57 0A A0 5F C3 C5 7F 42 84 D9 E6 35 66 B4 03 ") - (data "11 9B B9 15 CB 8D EB CE FB 2A 07 E6 6D B0 A9 42 8E 94 F1 A3 17 6D 15 81 A3 40 11 F5 6F 02 D4 16 ") - (data "B7 72 2B 78 16 DB 60 93 99 BA 44 87 27 23 CD 05 EB 2C 6E 52 F3 FD B4 0A 9E 01 19 D2 A6 1F 10 4C ") - (data "5C FC 7C EF 6F 1A EF 4F 8E 1D 28 63 F7 BE 41 D7 8A 43 84 E7 96 65 F5 D3 33 8F 02 BE 7C F9 32 B3 ") - (data "6D FB 5D C6 C9 EE 0C C0 1B 66 80 C8 7F 0B 00 3A 8D 0E 0F C3 3F AA 8E 3D 44 F5 D9 2F 6D 62 D6 69 ") - (data "88 78 EA 0D 36 23 A8 3C A7 5A 16 A6 22 49 DB A4 2D 97 CB AB 7A BD D9 CF 62 A5 08 DF F3 66 FF 3B ") - (data "CD D1 17 EF 66 B5 5A 3A AA 07 E7 6D B0 A9 F8 BE AC 29 E3 47 8F B3 7D F4 02 67 35 FA CE 31 C0 1D ") - (data "1F 64 12 B8 0D 83 DB F7 2F FA B4 60 D0 D4 00 2F 3C F0 24 47 60 B3 13 F3 77 E5 F8 1B 9D D8 8B 3C ") - (data "71 2F E9 E8 4C 84 4A 99 0C A5 4F 5C 3A 01 C4 AB D5 6A 50 AF 37 B5 7A BC 14 49 D2 24 52 76 4D A0 ") - (data "6C BB 51 BA 32 4D 73 AC BA A0 CF E7 F3 81 65 D9 5D 68 07 4B 16 CA 5D 68 B9 19 AA BE A1 8A 9D AE ") - (data "0A A7 D0 60 B3 68 D2 16 CE 23 34 96 8D 90 BE 49 0B DC AF 56 37 4C 72 38 66 53 D9 0F AB D5 F2 52 ") - (data "53 5C 97 2E DA 33 BA A7 71 AC 0E E2 51 1E AD C0 59 8D BE 1B 10 F1 25 C0 67 0C E0 BE 63 79 34 4E ") - (data "86 00 02 BF 66 00 06 08 EB D1 CB 0F 35 34 2E C3 22 80 CA 14 11 7F A3 63 42 2E 39 30 4B A3 0E 48 ") - (data "B2 35 A2 AA 89 4B C7 5D 77 CC C9 2A AD A5 85 4E 83 CD AC FD 5B 32 EC 46 CF 9A CD E6 25 80 81 EA ") - (data "35 56 AB A5 93 2D 23 24 3F CC B8 25 E2 AE AE 0B 57 67 A7 5B EE C4 6C 74 D4 3B 30 AB 37 D8 3C 9E ") - (data "80 48 5F 38 35 63 9F 0A 45 35 EE C4 75 DD A9 65 59 97 BA D9 7B 45 11 14 84 4C 77 C3 EF A3 11 F6 ") - (data "90 4B B4 33 1B 43 22 3D F7 F4 B1 1A 6C 46 29 35 4D BC 8E F5 AC AC 73 13 F1 5B E8 2E 60 84 37 5E ") - (data "7C 37 F0 78 0A 88 BF D1 89 BD 28 AB 82 A7 58 EE 4E 58 00 00 12 73 49 44 41 54 6E A7 E1 B4 9D 59 ") - (data "35 1D B1 F5 23 FF 83 C5 8F 1D 64 68 4A 9A 87 B4 D4 7E CD 06 9B 99 26 A4 A0 2E 4E 7A 61 B0 28 61 ") - (data "0B 07 E5 D4 D7 C5 62 B1 08 CD E8 37 9A C3 CB 09 BF 5F AF 97 9D 8C F1 69 CA CF 6A B9 13 F3 71 1B ") - (data "6C 96 C0 49 58 79 13 50 7E 56 5C D7 1D 12 A1 87 0A E7 0D 66 DC 32 1B 3F 64 11 37 E1 19 0A 69 B0 ") - (data "99 46 B8 26 E9 FC DE 4F A2 13 7C A9 02 87 7A 7F CC E2 5E 5B 8E 2E 72 3D F4 CC FC 1E 1A 0F 22 11 ") - (data "6E 98 E9 87 7A EF DF 4A F1 1C 1B 8A AA 7F C3 5C 54 FD 8D EC 14 DD 60 B3 8A 8E D8 59 EB 28 B8 AE ") - (data "3B AD D5 8C 4E 15 85 A6 02 AB 02 DE D5 6A F1 C1 8C 01 D5 D4 04 72 5D 77 A8 D9 2C EF 2C CC 24 51 ") - (data "66 2B 72 F8 BD DE E8 B2 40 D7 CC C6 0F AE EB EA 9A EF EF D1 A8 11 53 DA C4 7C 0A 0D 36 8B 47 E5 ") - (data "F7 A9 F3 DC 17 8B 6E DC C9 7C 3E 1F 57 34 6F DC 11 E1 DD D7 AF F3 76 D6 0D AD E6 F3 54 80 DB 55 ") - (data "BD F0 DF A9 74 82 3F 9A 8B 8A 60 68 17 4B 8A D2 E8 7D BE 04 70 B9 1A 7D E7 10 FC 36 C3 68 3F BC ") - (data "86 3F 63 18 B3 3A EA 53 EA EA B9 A5 22 38 31 7F 57 8E BF 29 A2 C1 66 41 68 B8 A7 54 1E D0 F2 27 ") - (data "AE 3C EE BA 70 A1 72 36 29 C8 C5 C7 E5 D0 35 E0 0F D3 FB C4 DC 53 59 9F A0 C0 8A A3 65 6E 7F D3 ") - (data "6A B5 E2 FA 96 1D 24 14 1B 97 E7 E7 AD 71 70 BD E2 32 5F 02 E8 3A 48 F1 FD 4B 6B 53 72 18 B5 B1 ") - (data "95 39 31 9F 42 83 CD 12 50 99 AF 8E 15 AF 95 29 EE A4 CC 79 83 19 B7 86 81 E1 72 B9 2C A0 E9 AD ") - (data "7A 83 CD 22 B2 72 5D D7 1D 5A 96 AD 98 52 7F 1A 9D E0 1F 6D 0C CE 86 AC 7D A5 54 29 22 FE 46 C7 ") - (data "95 53 6E 05 4F 1D FF BF 92 E5 A4 F4 89 AB 88 3A 0A 61 30 EA D0 B6 ED AE EF A3 1F 56 B3 CD 14 9F ") - (data "C3 8C 8F 00 4D 92 6A E6 1C A2 A8 06 9B 1A EF D7 AE 5F 11 B6 70 E8 EB 5E 2B DC 81 3A 61 20 7D 3F ") - (data "C8 AC CB BC 28 DC 30 D3 50 F7 FE 26 11 8C 4B 4D 30 84 05 D9 4A 44 55 B8 A4 75 8F DE 39 E7 02 C0 ") - (data "51 4A E2 BB 6E 72 21 3A 9D 7B 5F 34 79 AB E8 6E E6 8D B0 50 5F 3F CC 80 CC F2 5C DF 84 F3 E9 F0 ") - (data "EB D7 E2 CA 7F 18 06 9B CC 2A F7 B6 B8 4D 73 28 F8 BA 69 C7 1D B3 C1 66 94 D2 23 BF BC 8F 2F A7 ") - (data "CC 0F 17 42 62 FC 5C EB 7D D2 32 8B 1F 83 F5 F8 E5 41 45 F0 58 C6 2F 1C 26 10 1C DC 31 0C 36 83 ") - (data "CE CE F4 C0 A2 C8 CC 0B C3 C0 34 E8 73 45 D3 0A BA 1B 3F 19 5A AD 56 3B 14 F6 9D A0 D6 0D B5 F7 ") - (data "8F 91 FB 2B 3C 36 5A AD 56 7B BD 46 7B D3 F7 8B 99 CD 60 E3 08 00 3C DB D4 C3 61 E6 19 73 6D 26 ") - (data "CF F4 71 29 DD 82 C3 E0 C5 21 1D E5 E3 E1 82 72 6A 14 57 FF 46 38 35 C2 89 67 72 E4 61 3C 59 42 ") - (data "EB CB 0C 40 C9 16 11 41 A8 8E C8 73 3D 39 EA 40 04 25 CA EF 26 EE EF 56 85 DD 40 5A 05 E7 8E 86 ") - (data "13 F3 77 E5 F8 1B 41 10 04 41 10 AA A7 74 81 C3 88 11 38 86 7A 89 F8 63 41 A1 19 F2 01 27 12 21 ") - (data "2E 08 82 20 08 C2 61 4A 17 38 14 D3 21 FA 50 5C CE C9 51 40 FD 1B 41 10 04 41 10 AA A7 74 81 53 ") - (data "C3 2A D6 95 93 54 63 E6 D8 14 55 FF 46 10 04 41 10 84 EA 29 DF 82 13 14 FB 3B 58 90 CF 38 ED 38 ") - (data "1C 27 E6 EF 12 7F 23 08 82 20 08 27 4E 35 75 70 88 A7 87 DC 3D 1C 88 88 D2 52 AD 43 2B 8C 43 E0 ") - (data "0E 0C 36 01 80 7D 63 D2 E8 FD 3E 48 7B 6F 11 F5 6F 4E 05 D3 34 CD 7A FD FF ED 88 C9 7A 1D B3 53 ") - (data "28 A5 AD CA E6 33 10 79 6D 22 6A FB BE 31 21 F2 16 45 14 B0 7A 0C 1C FA 0E 81 FC 6D 3D 2C CB EA ") - (data "30 D7 CC 6D CA 7C 50 58 71 BD FE EF B4 AC 8E DA 82 20 08 55 50 49 07 B4 B0 31 E6 A1 0E C7 77 F5 ") - (data "EE A7 42 D3 C5 D7 A3 EF BB 80 DF 45 50 8C E8 60 31 B7 1A 37 FE 91 D6 70 B3 CC FA 37 E7 E7 F6 2C ") - (data "AE 60 54 58 62 7F 6A 18 18 CE E7 F3 5C 29 B6 61 71 B9 4B 22 BC 8E BB 16 11 0F 74 BA 32 6F B0 2C ") - (data "EB 0A A0 9F 92 8F A2 6B 66 8C D7 EB FF 0D B3 2E 96 69 9F 01 41 C9 F3 2B D5 5E 2E A6 69 9A 8D 46 ") - (data "F3 FF B2 8C 65 0B FF 18 77 CF 2C CB 5E 20 BE 88 E0 9D EB CE 95 9F F7 40 D4 7C D3 27 E2 3E 92 8B ") - (data "2A 7E 60 36 86 AA 62 C7 34 4D B3 D9 6C 5E 86 45 0F 93 0A 97 DD 30 D3 30 CF F7 27 08 82 70 2C AA ") - (data "12 38 0E 11 FF 76 E8 35 9F F9 5F 45 B8 7C D6 A3 8B 3E 88 06 40 72 A5 49 15 81 52 E6 78 C3 B6 0D ") - (data "FF 51 3B 9A AE 5D F7 2F 47 F7 1A C1 22 FE CD 58 A3 74 FE 07 D7 9D F7 75 AE 61 59 F6 14 EA 95 8C ") - (data "6F 56 AB A5 A3 B3 48 06 8B 7B 73 98 20 6C 32 5D 23 AC 4A 7A F0 BB 55 87 FF 75 C8 72 94 FE DD AA ") - (data "7F 9F 61 D5 E5 2B 9D CA A9 CC F4 F3 D7 AF 7F 25 3E DB 81 C5 86 C6 7A 15 59 F9 BD EB BA 97 EA C7 ") - (data "0B 82 20 1C 9F 4A 5C 54 8D DE EF 93 F5 F8 E5 C1 D7 08 46 17 39 1A 81 85 62 64 88 14 61 03 E0 96 ") - (data "99 FA 75 B5 D6 0E 4E CC DF 73 C7 DF EC B6 6D A0 EB FD 72 E2 BB BB 6A 7E 65 DB F6 40 A7 D3 6C 58 ") - (data "1A 7D 02 F0 19 B0 B1 08 D1 55 B4 F4 7D B8 C8 0D 22 E2 E1 8D 65 59 0B CD 45 EC C5 F6 FC 46 7F F3 ") - (data "C7 6D 85 4F 74 B1 15 40 2F EA F5 6F FA 50 74 47 1E 58 84 EF 98 69 B0 FF 19 00 BA 04 F0 66 73 8D ") - (data "46 A3 31 00 90 FA 19 88 F0 EE D0 DF F7 EE FD 7B 22 3A 28 96 E6 F3 C3 6E B1 70 6C 04 EC 5A E9 5C ") - (data "77 AE B5 91 08 7A E0 E0 57 BA 7F 57 D0 93 69 B9 5C 4E 36 02 EE FC BC E5 18 86 EF 44 C7 4C E4 27 ") - (data "8A BB CD B3 41 84 CD B3 F1 71 DF 52 18 88 34 CF 09 BE D3 7B 81 FC B7 70 03 0A 82 F0 B4 A8 C4 82 ") - (data "03 00 EB 8F 17 93 43 71 38 44 B8 A9 BD FE 94 29 D8 38 B4 DA 24 37 14 24 BE 86 8F 61 BD F7 79 A8 ") - (data "7C DE 98 B1 82 F1 B1 DE FB 94 DA 87 23 89 A8 6B 87 08 BD 43 6E 28 CB B2 87 B8 5F B8 D5 77 FD A1 ") - (data "D5 63 1A 11 06 89 56 0D DB B6 07 CC B8 77 1D AE 56 CB 7F A8 58 59 F6 AC 20 B1 D6 9F E8 E7 60 C6 ") - (data "C7 AF 5F E7 A9 F7 2E 74 21 4D B0 15 47 37 B5 9A D1 8D 8B 17 B2 2C AB 1F 6D 2A 59 AB 19 FF CC 1A ") - (data "5B 14 71 2F 69 B9 92 F6 D9 B5 E4 E8 59 E1 F6 3F 8F 8A F5 64 FB 3D 1E B6 2C 6D CF FD 6C B2 11 2D ") - (data "2A D6 9E F0 7B BE 02 B8 FF 77 89 75 12 04 E1 E9 50 7E 25 E3 10 F2 E9 60 3C 09 33 5E F0 E8 DB 76 ") - (data "96 73 72 4C 77 6C 22 DC 30 F3 7B 9F F9 5F F5 D7 9F 1D 1D 71 13 9C B8 CC FA 37 DB CE BF CB E5 32 ") - (data "E6 7C D1 B6 F4 EA 1D 9A 43 97 8E 92 B8 01 80 F9 7C 3E 08 63 7E 00 00 8D 46 43 49 BC 19 3B 05 10 ") - (data "E3 53 E6 37 7D 59 82 F7 A8 59 01 EA F5 E6 10 11 71 B3 5A 2D 9D 24 C1 12 C4 C2 6C 1B CE AD D7 9C ") - (data "49 80 86 8D 22 37 96 8D 49 96 73 6C 88 5A E9 74 1A FE 85 16 96 A8 B8 F9 51 C5 AA 36 9F CF 07 44 ") - (data "E8 25 89 90 56 AB D5 8E 3C 4B 37 69 E2 06 08 02 98 5D 77 DE 11 71 23 08 C2 63 A4 B2 6E E2 06 BC ") - (data "B1 87 DA 2F 87 5E F3 51 EB 22 43 36 55 1D FE D5 9A EB D1 05 7C 52 47 7D 4A DD E4 00 E2 24 2A E8 ") - (data "3F 75 BF 78 C7 89 0F E6 9A 49 74 DF 79 FA 46 E5 A4 E1 6E FB 75 F0 7E DC AE D7 6A 31 2F 86 81 E1 ") - (data "C6 8A 43 44 6D 95 6B 05 CD 29 EF FF 19 BB F8 A9 1E B7 21 EB 67 60 C6 98 08 E1 E2 CD 0E B2 65 E6 ") - (data "DD 8B 12 55 31 16 3F 1E 76 22 C6 51 8D 73 19 57 9B 67 2F B0 B0 CC 87 AA EF 4C 0B 48 5F AF D1 8E ") - (data "B8 BC 24 60 58 10 84 27 4F 65 02 87 7A 7F CC BC 8F 2F 6F 0E 56 30 36 D0 47 86 45 29 AC B1 33 C8 ") - (data "3B B6 3D 9C B8 17 F2 C6 DF 84 19 41 9B 7F C6 9E CB 30 7C 87 B7 1A 4B E9 9A 44 3C D8 BE 1F 97 AA ") - (data "01 BD 41 BA B5 FF 36 F8 FF C3 16 B1 87 D7 BA BF 47 77 71 BB FB C0 D5 B2 89 F1 A1 EB F9 FC 2F 85 ") - (data "8C 30 FF DE 5A 41 C4 03 F5 A0 64 9A 6E 84 C1 A1 AE E0 8A E7 70 EE 47 11 A6 4A 67 47 C5 4A B7 4B ") - (data "60 BD D9 B8 8F 70 AB 62 61 C9 0E BF 32 4D D3 94 CC 28 41 10 9E 32 95 09 1C 00 80 8F 21 08 0F AC ") - (data "38 CC 78 B1 1C 5D 74 4E A1 80 5E 6C FD 1B E2 EB 87 7F D4 63 57 B8 1C B6 06 05 01 B6 DB 40 59 66 ") - (data "63 98 76 DE 30 E6 E3 7E 71 74 DD 7C E9 E5 49 44 5D 39 00 66 81 68 8B C2 9D D0 8A 72 2F 6E 56 AB ") - (data "FF 29 C5 DE 44 82 9E EF B2 A4 AE E7 81 19 CE C6 C2 91 B7 B6 0C 14 AC 74 0F A1 88 2B 8A 0A 17 37 ") - (data "F5 3A 66 9E B7 FD 77 A3 D1 9C D9 B6 7D 65 18 C6 F0 31 D5 43 12 04 41 50 A5 52 81 93 E4 A6 32 82 ") - (data "09 BE 5F E5 78 0E 12 13 7F C3 B9 77 F5 00 33 39 1B 4B 43 AD 56 7B 70 BE D0 C2 73 85 7B 01 C1 EF ") - (data "55 16 DB F5 9A BB 9B C5 99 88 B5 C4 8D 61 F8 E6 46 74 29 BA 66 A2 56 9E 17 49 29 D7 CC B8 AD D7 ") - (data "A9 EF BA E9 8B FC 5E FC 4F 66 81 C6 CC DA 56 89 50 5C 85 B1 4B 94 4B C8 AA 5A E9 F6 89 0A AC 7A ") - (data "FD 70 BC 5A 1E BE 7C F9 32 B3 2C EB 7D A4 76 D1 19 33 DE 7A 9E FF F6 FC DC BE 0D C6 4A 13 22 7F ") - (data "22 31 37 82 20 3C 05 2A 0B 32 06 42 97 52 9C 25 84 D0 E5 91 53 68 D1 3F 5D 52 7A 63 4D F2 5F 61 ") - (data "DB 9A C2 F7 FD BE 6D DB 03 DB B6 07 E7 E7 F6 D8 B2 EC 69 28 16 C2 DD BF 7A ED 11 A2 ED 79 89 48 ") - (data "77 9C 9A 19 6C 5B F7 4B EA 91 84 E7 9E E7 4F 6D DB 56 09 FC 8D 8C 43 37 D6 69 FB F9 B3 C4 CF 34 ") - (data "9B 4D 67 FB 2F 3F D7 E2 AE 1A 80 1D 25 2A B0 98 71 5B 96 45 C5 75 DD CB 30 45 7E A7 75 0A 11 9E ") - (data "13 E1 35 11 FF 02 D0 9F E7 E7 F6 4C F1 3B 13 04 41 38 59 2A 15 38 00 02 37 D5 61 CE D6 58 1F B5 ") - (data "98 58 52 6F AC 86 5A FD 9C 58 F6 5C 3B 60 C6 DB CD 7F A1 6B 26 14 36 74 CD 6C FC A0 57 93 86 DA ") - (data "DB F3 F2 4C 67 5C D1 B8 1B 95 D8 13 E6 6D 8C 92 EB CE E9 D0 7F 44 E8 61 1B 1C 7D C6 4C 0A 9F C5 ") - (data "B8 1F 07 73 6D A6 FC 01 B0 2B F0 90 A1 66 4B 10 14 BC 39 97 B6 40 DC 3B D7 56 00 1E B2 D2 1D 22 ") - (data "DA 82 81 88 66 79 AE 9F C6 7C 3E 1F AC 56 CB 36 C0 3F 02 FC FE 90 C5 8A 08 CF 99 31 7A E8 7E 14 ") - (data "04 41 78 3C 54 2E 70 C2 94 ED 83 CD 37 89 F8 F2 98 56 1C 8E 0B 30 2E 20 FE 06 11 0B 45 58 7C EF ") - (data "7A FB DF F6 EF AB D5 FF BA FA 31 20 7C 7F CF 74 DD 0B 91 80 E1 D4 D8 13 55 57 CE 7C 3E 1F AF 56 ") - (data "4B 67 9B 82 CE AF 82 34 65 35 EA F5 6D 7A B9 0A 51 D1 A5 1A D4 BB CB 56 5C 65 7B FF CE 68 36 E7 ") - (data "BA 3B D5 D8 96 C5 62 B1 70 5D 77 E8 BA EE A5 EB FE E5 B8 EE 9C 98 8D 1F 00 7C 88 1E 47 E4 F7 8F ") - (data "33 42 41 10 84 FC 54 6F C1 01 C0 1C 1B 44 79 5C 2B 0E 1D 16 38 45 C4 DF EC BA 76 8C 7E B0 B0 04 ") - (data "FF 6D C4 02 11 9E 87 D5 78 75 51 6D 99 B0 43 98 E9 B4 B1 2A 7D 48 38 14 80 9E 2B 67 B1 58 2C A2 ") - (data "D6 88 F5 1A 6D FD 11 A6 63 DB 76 37 E2 DE F9 98 2D 33 68 9B BD 94 27 B3 A8 C8 5A 3A 55 13 D6 BC ") - (data "E9 07 96 9D 7B C4 4D 25 08 C2 A3 E5 28 02 A7 8E FA 15 4E CC 8A B3 1C 5D EC B8 90 F6 98 E4 3D 7F ") - (data "D4 CA B0 6F 29 A9 D5 A8 8F FB FB 41 3F E9 BB 06 B6 D6 94 70 91 55 1C 13 0D B6 FF 9F 9E AD A5 EF ") - (data "CA 89 C6 06 79 CA C2 41 47 0C 31 47 CB 04 18 DA D9 47 D1 7B 4D 94 EF 7B 66 36 9C ED BF B2 B9 BA ") - (data "98 B9 9D 67 0C 79 A9 3A 7B 4D 10 04 A1 2C 8E 22 70 A8 37 59 9C 9A 15 A7 96 10 3C 9B 37 FE 26 CD ") - (data "B5 F3 E5 CB 97 59 54 6C 00 FE D0 34 CD 4C 22 6F 77 91 8D C7 B2 EC 61 D4 F2 A1 E6 16 53 77 E5 84 ") - (data "C2 E1 BE 1F 56 BA EB 6C 1B 3B 44 E4 29 59 0E C2 56 10 F7 B1 4B 59 D2 BB B3 04 05 C7 B1 1B 0B 44 ") - (data "CA AE C2 F5 FA BF F7 C7 12 E1 B9 8E 3B 2F 4D D0 9A 21 AA E7 8B 5E FB B1 59 A1 04 41 10 A2 1C 45 ") - (data "E0 00 A9 56 9C B7 59 DB 37 64 A5 CC F8 1B 15 D7 4E 50 D8 2D 9B AB 8A 39 9A 56 CD 97 49 0B 9A 69 ") - (data "9A E6 F9 B9 3D C6 B6 49 E5 DD 7A BD EC 2B 5E 49 C9 95 63 59 56 87 C8 BF 1F 53 B4 08 61 C2 B9 27 ") - (data "DB FF A7 7E D2 22 6F 9A A6 B9 DB AF 0B 77 A1 15 4C 9B BD E2 86 39 2B 18 AB C7 33 45 09 EE E5 56 ") - (data "F8 7A 1E 0F D3 DE 63 9A A6 69 DB F6 00 A0 3F 93 8E 6B 36 9B 4E A3 D1 9C A8 5A F6 D6 6B FF 7E E3 ") - (data "61 18 B1 09 01 82 20 08 27 CF D1 04 4E 8A 15 07 9E 91 EE 32 29 94 12 E3 6F 54 5D 3B 59 5D 55 EB ") - (data "F5 FF 86 9B F7 05 E2 A8 39 39 24 10 5A AD 56 BB D1 68 4E A2 05 F5 00 56 6A 87 A0 E2 CA 39 3F 6F ") - (data "39 61 33 D1 09 22 B5 7C 54 DC 1E AE EB 0E 23 7D B1 CE 3C CF 1F 1F FA FC 9B CF 80 88 B8 01 38 B1 ") - (data "5F 55 12 2A 55 99 55 68 B5 5A ED 3C B5 74 76 2D 78 FC CA B2 9E C5 7E 87 96 65 5D 35 1A CD 59 D0 ") - (data "62 23 F5 5A 1D 00 2F 00 FA D3 B2 EC 61 5C FA B7 65 59 1D CB 7A 16 7D 36 3E A4 B5 7F 10 04 41 38 ") - (data "65 2A EB 26 7E 08 1E 39 A6 47 AB 19 62 62 5F 88 F1 73 AD F7 A9 C4 92 F5 01 CB D1 45 C7 A0 C3 3B ") - (data "61 66 FA 21 7F 8A F8 B6 8B 73 5A C7 EE F3 F3 67 97 41 3D 92 FB 7E 4C 1D 15 01 62 DB 76 97 19 A3 ") - (data "BD 3F DF 60 6B 95 08 17 BA 00 66 DC 12 71 57 75 51 8F 8E 4B 83 D8 4E E3 87 08 9B 4D 4E B0 FB 3C ") - (data "DC 6C 7B 27 B1 89 DD 80 EA 3B 80 9D AC C2 24 BC DE 9F 80 7A B7 F3 87 E7 B0 87 41 9A FE 76 6C C1 ") - (data "BD 0D 02 AC F3 75 12 DF 3D D7 E1 C6 AB C9 F5 92 A2 CF DE 2E 51 61 C4 7B F1 67 7A 1D D0 05 41 10 ") - (data "4E 91 A3 59 70 80 C0 8A 03 E6 D8 C9 99 09 83 2A 5C 55 65 C6 DF 04 A8 67 E9 64 75 55 CD E7 F3 31 ") - (data "11 7A D1 EE E0 08 16 DC 37 E1 7F 1B 61 70 07 F0 FB F5 7A A9 D9 25 7A 6B 85 52 E0 43 AD 66 FC 53 ") - (data "47 DC 00 9B 14 77 76 1E 7E 06 7E 15 DE C3 9D CF B0 5A 2D DB 39 AB EE E6 2A 10 18 BA 02 DF EC 8D ") - (data "0D 81 25 87 5F 45 D3 F7 55 70 5D 77 B8 FF 1D 46 CE B5 23 52 98 F1 31 EC 20 9E 18 AF 16 5A 05 3F ") - (data "E0 81 3B 78 73 4E 7E 85 48 AC 54 D0 C1 5C C4 8D 20 08 8F 9F A3 5A 70 36 AC 3F 5E 4C E2 5A 24 10 ") - (data "E1 A6 F6 FA 93 66 B5 5D CD EB 8F 5E 8E B1 35 CD 47 2E CE D7 F5 D7 9F 9D 3C E7 36 4D D3 DC 14 72 ") - (data "23 F2 16 2A 0B 72 F4 3D 80 7E 6F A4 C0 9A C3 4E 34 28 38 8C FD 99 AE 56 AB 71 96 54 E8 A0 47 56 ") - (data "2D 75 C1 2E A0 8F 13 80 E0 33 00 E8 44 0B E7 11 F1 84 99 67 59 3F C3 3E AD 56 AB BD C9 D8 5A AF ") - (data "FF 3B D5 3D E7 FE F7 B4 8F EA F7 7D 88 20 8E 89 0E 59 94 A6 CB E5 72 92 E5 F3 07 2E 3F EE 18 C6 ") - (data "AE F0 F2 7D 5A 48 8B 06 41 10 9E 1A 27 21 70 92 5C 44 00 C0 CC EF 1B BD CF A5 65 56 AD C7 2F 17 ") - (data "38 E0 26 63 A6 77 8D DE EF 83 B2 AE 2B 08 82 20 08 42 39 1C D5 45 B5 A1 D9 FB 3C 65 A6 77 71 AF ") - (data "13 D1 4F EB D1 45 BF 8C 6B 97 5D FF 46 10 04 41 10 84 EA 39 09 81 03 00 8D DE EF 03 A2 FB FE 45 ") - (data "0F 21 BA 0A C5 48 A1 94 1F 7F 23 08 82 20 08 42 D5 9C 8C C0 01 00 C3 F7 BA 88 A9 8D 03 E0 CC 20 ") - (data "9A 14 2D 72 4A EE 3F 25 08 82 20 08 C2 11 38 29 81 43 BD 3F 66 60 A3 9F 70 C8 99 41 34 2E B4 95 ") - (data "43 A9 FD A7 04 41 10 04 41 38 06 27 25 70 00 A0 DE FB F7 38 29 1E 07 C0 73 DF 58 4D 8A 10 39 12 ") - (data "7F 23 08 82 20 08 4F 93 93 13 38 40 10 8F 03 8E EF 6E CD 8C 17 BE B1 CA ED AE 92 F8 1B 41 10 04 ") - (data "41 78 9A 9C A4 C0 01 80 1A 1A 97 49 41 C7 CC 78 91 37 26 47 E2 6F 04 41 10 04 E1 69 72 B2 02 87 ") - (data "7A 93 85 E1 37 9C C4 CC AA 30 F0 78 3D FA 5E BB C4 7E 70 11 89 BF 11 04 41 10 84 A7 C8 C9 0A 1C ") - (data "40 5D E4 80 FC D1 6A F4 DD 40 E7 DC 12 7F 23 08 82 20 08 4F 97 93 16 38 80 B2 C8 01 11 BF 5D 7F ") - (data "BC 98 A8 F6 AE 92 F8 1B 41 10 04 41 78 BA 9C BC C0 01 D4 45 0E 98 5E 79 54 9B 7A A3 97 A9 6D 1D ") - (data "24 FE 46 10 04 41 10 9E 2E 8F 42 E0 00 5B 91 03 C6 C7 94 43 CF 98 F0 CB FA E3 C5 64 35 FA CE 89 ") - (data "3F A1 C4 DF 08 82 20 08 C2 53 E5 24 9A 6D EA B2 1A 5D 5C 11 D1 4F 4A 07 33 3E D4 E0 0D A8 F7 C7 ") - (data "6C F3 A7 A4 E6 9E CC F4 83 B8 A8 04 41 10 04 E1 71 F3 68 2C 38 51 1A BD CF 97 60 A3 87 F8 B6 0E ") - (data "5B 08 6F 3C AA FD 67 3D 7A 39 DC A4 94 13 8C D8 AC 2B 11 37 82 20 08 82 F0 F8 79 94 16 9C 0D 3C ") - (data "FA B6 ED 1B B5 31 33 5E 68 BC ED 16 C0 F3 83 AF 10 5F D7 5F 7F 76 8A 18 9B 20 08 82 20 08 C7 E3 ") - (data "51 5A 70 36 50 EF 8F 59 ED F5 A7 4E 4A 6B 87 7D 0E 8B 1B 48 FC 8D 20 08 82 20 3C 15 1E B5 C0 D9 ") - (data "D0 E8 FD 3E A8 B1 F7 CF 02 32 A0 26 45 8C 47 10 04 41 10 84 E3 F2 A8 5D 54 87 58 8F BE EF 82 FC ") - (data "2B 24 58 6A E2 A8 77 3F 3D B9 FB 21 08 82 20 08 7F 47 9E 84 05 27 4A BD F7 EF 71 BD FB A9 0D E6 ") - (data "1F 11 C4 DB 28 91 5A 63 47 10 04 41 10 84 47 C3 93 13 38 1B EA BD CF C3 7B A1 A3 E0 BA F2 7D 9E ") - (data "54 30 2C 41 10 04 41 10 2A E0 C9 0A 9C 0D F5 DE E7 61 FD F5 67 C7 67 FE 17 18 1F 10 93 5A 4E A8 ") - (data "4D AA 1D 99 20 08 82 20 08 65 F1 B7 8C 39 09 BA 8F FB DD B0 9A F1 73 00 A8 71 E3 1F D4 9B 2C 8E ") - (data "3B 32 41 10 04 41 10 84 02 58 8E 2E 3A BA 9D C8 05 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 ") - (data "41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 ") - (data "04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 ") - (data "10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 41 10 04 ") - (data "41 10 04 41 10 84 0A F8 FF 65 82 93 78 58 28 0B 1C 00 00 00 00 49 45 4E 44 AE 42 60 82 ") - ) - ) +(kicad_wks + (version 20231118) + (generator "pl_editor") + (generator_version "8.0") + (setup + (textsize 1.5 1.5) + (linewidth 0.15) + (textlinewidth 0.15) + (left_margin 10) + (right_margin 10) + (top_margin 10) + (bottom_margin 10) + ) + (rect + (name "") + (start 110 34) + (end 2 2) + (comment "rect around the title block") + ) + (rect + (name "") + (start 0 0 ltcorner) + (end 0 0) + (repeat 2) + (incrx 2) + (incry 2) + ) + (line + (name "") + (start 50 2 ltcorner) + (end 50 0 ltcorner) + (repeat 30) + (incrx 50) + ) + (tbtext "1" + (name "") + (pos 25 1 ltcorner) + (font + (size 1.3 1.3) + ) + (repeat 100) + (incrx 50) + ) + (line + (name "") + (start 50 2 lbcorner) + (end 50 0 lbcorner) + (repeat 30) + (incrx 50) + ) + (tbtext "1" + (name "") + (pos 25 1 lbcorner) + (font + (size 1.3 1.3) + ) + (repeat 100) + (incrx 50) + ) + (line + (name "") + (start 0 50 ltcorner) + (end 2 50 ltcorner) + (repeat 30) + (incry 50) + ) + (tbtext "A" + (name "") + (pos 1 25 ltcorner) + (font + (size 1.3 1.3) + ) + (justify center) + (repeat 100) + (incry 50) + ) + (line + (name "") + (start 0 50 rtcorner) + (end 2 50 rtcorner) + (repeat 30) + (incry 50) + ) + (tbtext "A" + (name "") + (pos 1 25 rtcorner) + (font + (size 1.3 1.3) + ) + (justify center) + (repeat 100) + (incry 50) + ) + (tbtext "Date: ${ISSUE_DATE}" + (name "") + (pos 87 6.9) + ) + (line + (name "") + (start 110 5.5) + (end 2 5.5) + ) + (tbtext "${KICAD_VERSION}" + (name "") + (pos 109 4.1) + (comment "Kicad version") + ) + (line + (name "") + (start 110 8.5) + (end 2 8.5) + ) + (tbtext "Rev: ${REVISION}" + (name "") + (pos 24 6.9) + (font bold) + ) + (tbtext "Size: ${PAPER}" + (name "") + (pos 109 6.9) + (comment "Paper format name") + ) + (tbtext "Id: ${#}/${##}" + (name "") + (pos 24 4.1) + (comment "Sheet id") + ) + (line + (name "") + (start 110 12.5) + (end 2 12.5) + ) + (tbtext "Title: ${TITLE}" + (name "") + (pos 109 10.7) + (font + (size 2 2) bold italic) + ) + (tbtext "File: ${FILENAME}" + (name "") + (pos 109 14.3) + ) + (line + (name "") + (start 110 18.5) + (end 2 18.5) + ) + (tbtext "Sheet: ${SHEETPATH}" + (name "") + (pos 109 17) + ) + (tbtext "Micromelon Robotics" + (name "") + (pos 109 20) + (font bold) + (comment "Company name") + ) + (tbtext "In association with: ${partner}" + (name "") + (pos 109 23) + (comment "Comment 0") + ) + (tbtext "Client: ${client}" + (name "") + (pos 109 26) + (comment "Comment 1") + ) + (tbtext "${COMMENT3}" + (name "") + (pos 109 29) + (comment "Comment 2") + ) + (tbtext "${COMMENT4}" + (name "") + (pos 109 32) + (comment "Comment 3") + ) + (line + (name "") + (start 90 8.5) + (end 90 5.5) + ) + (line + (name "") + (start 26 8.5) + (end 26 2) + ) + (bitmap + (name "") + (pos 28.989 25.3822) + (scale 1) + (data "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" + "EIQK+P9lgpN4WCgLHAAAAABJRU5ErkJggg==" + ) + ) ) From bc8f5e74c359bd16ca394282da7ef5af7bb110e6 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 19 Nov 2024 13:29:22 +1000 Subject: [PATCH 125/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 9b70aa4..64598e4 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 9b70aa43c660c0dda9253d21312caf77c9e4b6f6 +Subproject commit 64598e47ba039d1aa8e7a22e9fcec75ff42aaa27 From 2f42e02e3e7785d11c7b47650e0280b2e450a3b8 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 13 Dec 2024 11:24:03 +1000 Subject: [PATCH 126/139] Added dry run when on dev --- .scripts/ki-ntree | 2 +- kibot-ci.yml | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 64598e4..c77c9e4 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 64598e47ba039d1aa8e7a22e9fcec75ff42aaa27 +Subproject commit c77c9e44d4a12437076e6cc0155a17c11aaf918f diff --git a/kibot-ci.yml b/kibot-ci.yml index 35a4602..65499fb 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -158,7 +158,12 @@ image: pcba_im=$fab_path/PCBA_$name_n_rev.png pcb_attach=$(echo "['$fab_path/${name_n_rev}_PCB.pdf', '$CI_PROJECT_DIR/Fabrication/${name_n_rev}_JLC.zip']") pcba_attach=$(echo "['$fab_path/${name_n_rev}_schematic.pdf', '$fab_path/${name_n_rev}_bom.csv', '$fab_path/${name_n_rev}-neo-pos_top.csv', '$fab_path/${name_n_rev}-neo-pos_bot.csv', '$fab_path/${name_n_rev}_ibom.html']") - poetry run python -m kintree_cli -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG', 'image': ['$pcb_im', '$pcba_im'], 'desc': '$desc_suffix', 'attachments': [$pcb_attach, $pcba_attach]}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 + + DRY="" + if [[ $CI_COMMIT_BRANCH == "dev" ]]; then + DRY="--dry" + fi + poetry run python -m kintree_cli $DRY -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG', 'image': ['$pcb_im', '$pcba_im'], 'desc': '$desc_suffix', 'attachments': [$pcb_attach, $pcba_attach]}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 done # - cp token_storage.json /tmp - | @@ -281,9 +286,7 @@ inventree_job: - job: outputs_all artifacts: true rules: - - if: $CI_COMMIT_TAG - when: never # Do not run this job when a tag is created manually - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + - !reference [.dev_rules, rules] script: - !reference [.commands, boms] From 972a452feaf2c7e50cf3ffafad516c9b202e96e7 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 13 Dec 2024 11:30:25 +1000 Subject: [PATCH 127/139] Tweaked inventree_job --- kibot-ci.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index 65499fb..af3644d 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -252,7 +252,7 @@ outputs_dev: - Fabrication/**/* expire_in: 1 week variables: - SUFF_SCH: run_drc print_sch + SUFF_SCH: run_drc sch SUFF_PCB: run_erc,update_xml,set_text_variables print_pcb script: - !reference [.commands, git_tag] @@ -277,6 +277,18 @@ outputs_all: - !reference [.commands, kibot] - !reference [.commands, neo] - ls Fabrication/ + +inventree_job_dev: + stage: inventree + needs: + - job: output_mech + artifacts: true + - job: outputs_dev + artifacts: true + rules: + - !reference [.dev_rules, rules] + script: + - !reference [.commands, boms] inventree_job: stage: inventree @@ -286,7 +298,7 @@ inventree_job: - job: outputs_all artifacts: true rules: - - !reference [.dev_rules, rules] + - !reference [.main_rules, rules] script: - !reference [.commands, boms] From 76ffd3df8b5ee6a2e35a9abbd8329735cda051db Mon Sep 17 00:00:00 2001 From: ac Date: Fri, 20 Dec 2024 09:54:13 +1000 Subject: [PATCH 128/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index c77c9e4..2effdd3 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit c77c9e44d4a12437076e6cc0155a17c11aaf918f +Subproject commit 2effdd3ad0ee23050f958d2d5a2aaf7c88e80a12 From cf1de7397a3521668707514b2c430caf440ae233 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 20 Dec 2024 13:21:49 +1000 Subject: [PATCH 129/139] Updated kintree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 2effdd3..c814d7b 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 2effdd3ad0ee23050f958d2d5a2aaf7c88e80a12 +Subproject commit c814d7b4ca100b7048e1355073d2867fc2d5c9b0 From 6e5a7fddc734bdd5d4373db1265dab759cee8399 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 20 Dec 2024 14:40:30 +1000 Subject: [PATCH 130/139] Update kintree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index c814d7b..f2f6007 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit c814d7b4ca100b7048e1355073d2867fc2d5c9b0 +Subproject commit f2f6007b7e29c5bc6d0033f377dd5cd504da21d7 From 80a2d5b1c0b1d4e78c0cfa27e5b096ce17a33b92 Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 20 Dec 2024 15:24:20 +1000 Subject: [PATCH 131/139] Dry run for all jobs except when on main --- kibot-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index af3644d..63ceb7d 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -159,9 +159,9 @@ image: pcb_attach=$(echo "['$fab_path/${name_n_rev}_PCB.pdf', '$CI_PROJECT_DIR/Fabrication/${name_n_rev}_JLC.zip']") pcba_attach=$(echo "['$fab_path/${name_n_rev}_schematic.pdf', '$fab_path/${name_n_rev}_bom.csv', '$fab_path/${name_n_rev}-neo-pos_top.csv', '$fab_path/${name_n_rev}-neo-pos_bot.csv', '$fab_path/${name_n_rev}_ibom.html']") - DRY="" - if [[ $CI_COMMIT_BRANCH == "dev" ]]; then - DRY="--dry" + DRY="--dry" + if [[ $CI_COMMIT_BRANCH == "main" ]]; then + DRY="" fi poetry run python -m kintree_cli $DRY -p $CI_PROJECT_DIR/Fabrication/$f --assembly "{'ipn': '$name', 'rev': '$TAG', 'image': ['$pcb_im', '$pcba_im'], 'desc': '$desc_suffix', 'attachments': [$pcb_attach, $pcba_attach]}" --settings $KINTREE_SETT --digi_token token_storage.json || FAIL=1 done @@ -289,7 +289,7 @@ inventree_job_dev: - !reference [.dev_rules, rules] script: - !reference [.commands, boms] - + inventree_job: stage: inventree needs: From 088d11339d25868061eccb94d36b6b16b572a0f3 Mon Sep 17 00:00:00 2001 From: andrewc Date: Thu, 16 Jan 2025 15:44:25 +1000 Subject: [PATCH 132/139] Updated ki-ntree and stopped allowing release to always succeed --- .scripts/ki-ntree | 2 +- kibot-ci.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index f2f6007..65cfbb5 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit f2f6007b7e29c5bc6d0033f377dd5cd504da21d7 +Subproject commit 65cfbb5b2a8a1f48f351edd147a3e6bd0a8f64d3 diff --git a/kibot-ci.yml b/kibot-ci.yml index 63ceb7d..eceb617 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -367,4 +367,4 @@ release_job: i=$(( i + 1 )) done chmod +x fab.sh - ./fab.sh || true + ./fab.sh From 4c53e1f07075b9243cea9b612977191ae3022c1f Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 3 Feb 2025 14:48:45 +1000 Subject: [PATCH 133/139] Fixed up footprint generation for kicad8 --- .scripts/foot_gen.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.scripts/foot_gen.py b/.scripts/foot_gen.py index 330da61..c16b33d 100644 --- a/.scripts/foot_gen.py +++ b/.scripts/foot_gen.py @@ -110,6 +110,7 @@ for foot in saved: path_split = vals[0].split(':') folder = sys.path[0] + "/../../libs/melonlib/"+ path_split[0] + ".pretty" load_foot = FootprintLoad(folder, path_split[1]) + print("Foot: ", vals[0], "; ", folder, ", ", path_split[1]) # foot.SetFPIDAsString(vals[0]) # Save the original postion of footprint + pads orig_cent = foot.GetBoundingBox(False,False).Centre() @@ -160,7 +161,7 @@ for foot in saved: # sorted_foots.sort(key=lambda foot: foot[0].GetY()) # Export the step file -os.system("kicad-cli pcb export step -f --subst-models --user-origin " + str(ToMM(brd_cent.x)) + "x" + str(ToMM(brd_cent.y)) + "mm -o /tmp/dummy.step " + sys.argv[1]) +os.system("kicad-cli pcb export step -f --no-dnp --subst-models --user-origin " + str(ToMM(brd_cent.x)) + "x" + str(ToMM(brd_cent.y)) + "mm -o /tmp/dummy.step " + sys.argv[1]) # Import the 3d model of the actual PCB dummy = FOOTPRINT(pcb) @@ -258,7 +259,8 @@ for [foot, pad_map] in sorted_foots: # kicad_mod.append(Circle(center=cent_mm, radius=radius, layer='F.Silkscreen', width=0.05)) for d in foot.GraphicalItems(): - if type(d) is pcbnew.FP_SHAPE and "F.Courtyard" in d.GetLayerName(): + print("Type: ", type(d), "Layer: ", d.GetLayerName()) + if type(d) is pcbnew.PCB_SHAPE and "Courtyard" in d.GetLayerName(): shape_type = d.GetShape() cent = d.GetCenter() - brd_cent print("Courtyard: ", cent, shape_type) @@ -406,7 +408,7 @@ for i in range(len(corners)): kicad_mod.append(Line(start=start, end=corners[j], layer='F.SilkS', width=0.1)) -# kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.SilkS', width=0.15)) +# kicad_mod.append(RectLine(start=[-brd_width/2,-brd_height/2], end=[brd_width/2,brd_height/2], layer='F.S', width=0.15)) final_model_path = "${KIPRJMOD}/../libs/melon3d/" + foot_path + ".3dshapes/" + foot_name + ".step" From 562abfd07abf9f2bc35013fb50c7af00f9802b57 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 3 Feb 2025 15:36:06 +1000 Subject: [PATCH 134/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 65cfbb5..26ff988 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 65cfbb5b2a8a1f48f351edd147a3e6bd0a8f64d3 +Subproject commit 26ff98818f03b57fa29b7d6d1a3ff301caf7794e From 5620b01227814d82eb57ef543e9a089cb3a7b768 Mon Sep 17 00:00:00 2001 From: andrewc Date: Tue, 4 Feb 2025 13:01:22 +1000 Subject: [PATCH 135/139] Changed kibot flags for drc/erc for kicad8 --- kibot-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kibot-ci.yml b/kibot-ci.yml index eceb617..bfe9f89 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -235,7 +235,7 @@ output_mech: paths: - Fabrication/**/* variables: - SUFF_MECH: run_erc,run_drc step pcb_render pcba_render + SUFF_MECH: erc,drc step pcb_render pcba_render script: - !reference [.commands, git_tag] - SUFFIX=$SUFF_MECH @@ -252,8 +252,8 @@ outputs_dev: - Fabrication/**/* expire_in: 1 week variables: - SUFF_SCH: run_drc sch - SUFF_PCB: run_erc,update_xml,set_text_variables print_pcb + SUFF_SCH: drc sch + SUFF_PCB: erc,update_xml,set_text_variables print_pcb script: - !reference [.commands, git_tag] - SUFFIX=$SUFF_SCH @@ -266,8 +266,8 @@ outputs_all: rules: - !reference [.main_rules, rules] variables: - SUFF_SCH: run_drc sch - SUFF_PCB: run_erc,update_xml,set_text_variables pcb + SUFF_SCH: drc sch + SUFF_PCB: erc,update_xml,set_text_variables pcb script: - !reference [.commands, git_tag] - SUFFIX=$SUFF_SCH From cbeb4df9c4036726729475a06c3f96f8ba0d47cb Mon Sep 17 00:00:00 2001 From: ac Date: Thu, 13 Feb 2025 18:00:38 +1000 Subject: [PATCH 136/139] Added new DRC rules to ignore when checking a panel --- .scripts/post_panel.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.scripts/post_panel.py b/.scripts/post_panel.py index c4e905d..812700d 100644 --- a/.scripts/post_panel.py +++ b/.scripts/post_panel.py @@ -25,6 +25,8 @@ src = json.loads(json_str) json_file = open(proj) json_str = json_file.read() dest = json.loads(json_str) +dest["board"]["design_settings"]["rule_severities"]["duplicate_footprints"] = "ignore" +dest["board"]["design_settings"]["rule_severities"]["extra_footprint"] = "ignore" dest["board"]["design_settings"]["rule_severities"]["lib_footprint_issues"] = "ignore" dest["board"]["design_settings"]["rule_severities"]["lib_footprint_mismatch"] = "ignore" dest["board"]["design_settings"]["rule_severities"]["hole_near_hole"] = "ignore" From 99af6dd08f1495ee84a4fa0078ff7c6a6b5babbd Mon Sep 17 00:00:00 2001 From: andrewc Date: Fri, 14 Feb 2025 09:57:20 +1000 Subject: [PATCH 137/139] Stop generating printed stencils for panels --- default.kibot.yaml | 7 +++++++ kibot-ci.yml | 21 +++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/default.kibot.yaml b/default.kibot.yaml index df37db6..74623da 100644 --- a/default.kibot.yaml +++ b/default.kibot.yaml @@ -255,6 +255,13 @@ groups: - stencil - interactive_bom + - name: pcb_panel + outputs: + - JLCPCB_compress + - neo_position + - print_pcb + - interactive_bom + - name: sch outputs: - bom_csv diff --git a/kibot-ci.yml b/kibot-ci.yml index bfe9f89..4aa745b 100644 --- a/kibot-ci.yml +++ b/kibot-ci.yml @@ -75,7 +75,6 @@ image: - !reference [.commands, sch_from_pro] - sch_arr=($SCHEMS) - | - cd $CI_PROJECT_DIR for i in $(seq 1 $END) do if [[ ${dir_arr[i-1]} == "./Frame" ]]; then @@ -93,6 +92,7 @@ image: - 'SEARCH="_panel.json"' - !reference [.commands, get_dirs] - | + mkdir panels cd $CI_PROJECT_DIR for d in $DIRS do @@ -103,14 +103,17 @@ image: NAME=$(echo "${FILE%.json}") PCB=$(find $d/*.kicad_pcb) echo "mkdring" - mkdir $NAME + mkdir -p panels/$NAME echo "panelising" - kikit panelize -p $JSON $PCB $NAME/$NAME.kicad_pcb - cp .gitlab/micromelon_default/micromelon_default.kicad_sch $NAME/$NAME.kicad_sch - cp $d/fp-lib-table $NAME/ - python3 .gitlab/.scripts/post_panel.py $NAME/$NAME.kicad_pro $PCB + kikit panelize -p $JSON $PCB panels/$NAME/$NAME.kicad_pcb + cp .gitlab/micromelon_default/micromelon_default.kicad_sch panels/$NAME/$NAME.kicad_sch + cp $d/fp-lib-table panels/$NAME/ + python3 .gitlab/.scripts/post_panel.py panels/$NAME/$NAME.kicad_pro $PCB done - - cd $CI_PROJECT_DIR + - cd panels || true + - !reference [.commands, kibot] + - mv panels/* . + - rm -rf panels/ neo: - 'SEARCH=".kicad_pro"' @@ -268,13 +271,15 @@ outputs_all: variables: SUFF_SCH: drc sch SUFF_PCB: erc,update_xml,set_text_variables pcb + SUFF_PANEL: erc,update_xml,set_text_variables pcb_panel script: - !reference [.commands, git_tag] - SUFFIX=$SUFF_SCH - !reference [.commands, kibot] - SUFFIX=$SUFF_PCB - - !reference [.commands, panel] - !reference [.commands, kibot] + - SUFFIX=$SUFF_PANEL + - !reference [.commands, panel] - !reference [.commands, neo] - ls Fabrication/ From 6b63a013efd8c165f8be4664f3bddc038fd7ce93 Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 17 Feb 2025 11:06:53 +1000 Subject: [PATCH 138/139] Updated ki-ntree --- .scripts/ki-ntree | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scripts/ki-ntree b/.scripts/ki-ntree index 26ff988..c66d40d 160000 --- a/.scripts/ki-ntree +++ b/.scripts/ki-ntree @@ -1 +1 @@ -Subproject commit 26ff98818f03b57fa29b7d6d1a3ff301caf7794e +Subproject commit c66d40daf798f7d876e2213f15f004e8f253672b From 1064d69ce0827217fd104baed986e33dddaff47c Mon Sep 17 00:00:00 2001 From: andrewc Date: Mon, 17 Feb 2025 14:47:30 +1000 Subject: [PATCH 139/139] Fixed up pre-push hook --- hooks/pre-push | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hooks/pre-push b/hooks/pre-push index 957611a..19e1085 100755 --- a/hooks/pre-push +++ b/hooks/pre-push @@ -1,6 +1,6 @@ #!/bin/sh -kimelon unlock all +kimelon git unlock all command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting '.git/hooks/pre-push'.\n"; exit 2; } git lfs pre-push "$@"